Fix animating between calc() values and numerical values#3439
Fix animating between calc() values and numerical values#3439mattgperry wants to merge 2 commits intomainfrom
calc() values and numerical values#3439Conversation
Code ReviewThank you for this well-structured fix! This PR properly addresses issue #3410 by ensuring animations from ✅ Strengths
🔍 Issues & Suggestions1. Logic Issue in DOMKeyframesResolver.ts:99-104 (Minor)The condition checks for type equality but then triggers measurement when CSS variable presence differs. However, the logic should verify that measurement is actually needed for the specific animation: // packages/motion-dom/src/animation/keyframes/DOMKeyframesResolver.ts:99-104
if (
positionalValues[name] &&
containsCSSVariable(origin) \!== containsCSSVariable(target)
) {
this.needsMeasurement = true
}Issue: The check Suggestion: The logic is correct but could be clearer: // When types match but CSS variable presence differs, we need to measure
// to resolve the calc() expression to a concrete value.
if (containsCSSVariable(origin) \!== containsCSSVariable(target)) {
this.needsMeasurement = true
}2. containsCSSVariable Implementation (Minor - Edge Case)The current implementation: export function containsCSSVariable(
value?: AnyResolvedKeyframe | null
): boolean {
return typeof value === string && value.includes("var(--")
}Potential edge case: This would match comments in CSS strings like export function containsCSSVariable(
value?: AnyResolvedKeyframe | null
): boolean {
if (typeof value \!== "string") return false
// Strip comments to avoid false positives
return value.split("/*")[0].includes("var(--")
}3. Test: Immediate Fallback Behavior (Question)The unit test in const mixer = mixComplex("calc(100% + var(--offset))", "0")
expect(mixer(0.5)).toBe("0") // Instant transition at 0.5Question: Is this the intended UX? With the measurement system triggered by the fix in The flow should be:
If this is expected: Consider adding a comment explaining why measurement doesn't apply in this code path (perhaps this is for cases where measurement wasn't triggered). 4. Test Duration Mismatch (Minor)// dev/react/src/tests/unit-conversion-var-to-simple.tsx:20
transition={{ duration: 0.05 }}
// packages/framer-motion/cypress/integration/unit-conversion.ts:16
.wait(200)Duration is 0.05s (50ms) but test waits 200ms. While this ensures the animation completes, consider using a more precise wait or documenting why 200ms is chosen (e.g., accounting for render delays). 5. Missing Edge Case TestsConsider adding tests for:
🔒 Security & PerformanceSecurity: ✅ No concerns. The changes don't introduce XSS, injection, or other vulnerabilities. Performance: ✅ Good. The 📋 Code Style✅ Follows repository conventions:
🎯 SummaryThis is a solid fix with good test coverage. The main suggestion is to clarify the test behavior around Recommendation: Approve with minor clarifications on the test expectations. |
Fixes #3410