Skip to content

Backport seven upstream Motion bug fixes - #80

Open
JonathonRP wants to merge 1 commit into
mainfrom
jonathonrp-backport-upstream-bug-fixes
Open

Backport seven upstream Motion bug fixes#80
JonathonRP wants to merge 1 commit into
mainfrom
jonathonrp-backport-upstream-bug-fixes

Conversation

@JonathonRP

Copy link
Copy Markdown
Owner

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 getFinalKeyframe speed fix (upstream 12.9.1) is deliberately not included; it's owned by the in-flight speed PR. The change to AcceleratedAnimation.ts is confined to a single condition inside supports() 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 height and top are now blocked by reduced motion")

animation/interfaces/visual-element-target.ts gated the reduced-motion bypass on transformProps.has(key), so a user with prefers-reduced-motion: reduce still got fully animated height, width, top, left, right and bottom. That's the accessibility defect this PR leads with. The gate now uses positionalKeys, which is the same set upstream moved to.

-visualElement.shouldReduceMotion && transformProps.has(key) ? { type: false } : valueTransition,
+visualElement.shouldReduceMotion && positionalKeys.has(key) ? { type: false } : valueTransition,

2. width/height unit conversion ignored box-sizing: border-box — upstream 12.36.0 ("Fixed height and width: auto animations with box-sizing: border-box")

render/dom/utils/unit-conversion.ts unconditionally subtracted padding from the measured bounding box. On a border-box element the bounding box already includes padding, so width/height: auto animations were measured short by the padding on both axes and visibly jumped. positionalValues.width/height now return the raw box when boxSizing === 'border-box'.

3. calc() divisors were zeroed, producing NaN — upstream 12.35.2 ("Detect divide-by-zero in CSS calc() values before making animatable templates")

complex.getAnimatableNone() mapped every parsed number to 0, so calc(var(--spacing) / 5) became calc(var(--spacing) / 0) and the resulting animatable "none" template evaluated to NaN. Numbers whose preceding template segment ends in / are now preserved; multiplication and everything else still zero out as before.

4. anticipate easing overshot past 1 — upstream 12.36.0 ("Ensure anticipate easing returns 1 at p === 1")

easing/anticipate.ts is now clamped: p >= 1 ? 1 : ….

5. WAAPI linear() easing emitted unrounded floats — upstream 12.17.0 ("Improved rounding for linear() easing curves")

generateLinearEasing concatenated raw float output, producing points like 0.16666666666666666. Points are now rounded to four decimal places, matching upstream, which shortens the generated easing string without perceptible precision loss.

6. transformTemplate was not checked in the accelerated-animation support test — upstream 11.18.2 ("Animations with transformTemplate not hardware accelerated")

AcceleratedAnimation.supports() never asked whether the element had a transformTemplate. WAAPI animations bypass the render pipeline, so such an element lost its custom transform ordering for the whole animation. One extra condition, plus the Owner['getProps'] type widened to declare transformTemplate.

7. Spring velocity leaked into duration-defined springs — upstream 12.34.3 ("Ensure velocity is never transferred to a time-derived spring")

getSpringOptions passed the inherited velocity straight into findSpring() when a spring was defined by duration/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 with velocity: 0.

The port's old test Spring defined as bounce and duration is resolved with correct velocity encoded exactly the buggy behaviour, so it has been replaced with upstream's two current tests (Time-defined spring ignores velocity and Time-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 errors
  • Biome reports no new diagnostics for the changed files; the two new test files are clean. (The repo has substantial pre-existing Biome findings that this PR does not touch.)

A changeset is included.

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-bot

changeset-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1be6ac8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
motion-start Patch

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

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@JonathonRP, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1ab6effb-b708-44b1-b287-ed0f1cd0c585

📥 Commits

Reviewing files that changed from the base of the PR and between 0adcef2 and 1be6ac8.

📒 Files selected for processing (16)
  • .changeset/quiet-koalas-backport.md
  • packages/motion-start/src/animation/animators/AcceleratedAnimation.ts
  • packages/motion-start/src/animation/animators/__tests__/AcceleratedAnimation.spec.ts
  • packages/motion-start/src/animation/animators/waapi/utils/__tests__/linear.spec.ts
  • packages/motion-start/src/animation/animators/waapi/utils/linear.svelte.ts
  • packages/motion-start/src/animation/generators/__tests__/spring.spec.ts
  • packages/motion-start/src/animation/generators/spring/index.ts
  • packages/motion-start/src/animation/interfaces/__tests__/visual-element-target.spec.ts
  • packages/motion-start/src/animation/interfaces/visual-element-target.ts
  • packages/motion-start/src/easing/__tests__/anticipate.spec.ts
  • packages/motion-start/src/easing/anticipate.ts
  • packages/motion-start/src/render/dom/utils/__tests__/unit-conversion.spec.ts
  • packages/motion-start/src/render/dom/utils/unit-conversion.ts
  • packages/motion-start/src/value/index.ts
  • packages/motion-start/src/value/types/__tests__/index.spec.ts
  • packages/motion-start/src/value/types/complex/index.ts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/motion-start@80

commit: 1be6ac8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant