Conversation
Code Review - PR #3442Thank you for this fix! This PR effectively addresses issue #3410 by ensuring animations from ✅ Strengths
🔍 Issues & Suggestions1. Potential Logic Redundancy (Minor - DOMKeyframesResolver.ts:97)if (originHasVar \!== targetHasVar && positionalValues[name]) {
this.needsMeasurement = true
return
}Issue: The check
Suggestion: Remove the redundant check for clarity: if (originHasVar \!== targetHasVar) {
this.needsMeasurement = true
return
}2. Comment Handling in containsCSSVariable (Enhancement)The current implementation: 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(--")
}Good: You correctly strip comments using Suggestion: Consider adding a test case for this edge case to ensure the comment handling works correctly. 3. Test Timing (Minor - unit-conversion.ts:15)// Component transition duration: 0.05s (50ms)
transition={{ duration: 0.05 }}
// Test wait time: 200ms
.wait(200)The wait time is 4x the animation duration. While this ensures completion:
4. Missing Edge Case Tests (Enhancement)Consider adding tests for:
These would strengthen confidence that the fix handles all variations correctly. 5. Type Safety (Very Minor - is-css-variable.ts:36-42)The function signature is good, but consider the AnyResolvedKeyframe type - does it include all value types you expect? The current implementation handles non-strings correctly but documenting the expected input types would help future maintainers. 🔒 Security & PerformanceSecurity: ✅ No concerns
Performance: ✅ Excellent
📋 Code Style Compliance✅ Follows CLAUDE.md conventions:
🎯 SummaryThis is a solid, well-tested fix that properly addresses the reported bug. The implementation is minimal, performant, and follows best practices. The suggestions above are minor improvements rather than blockers. Recommendation: ✅ Approve - This PR is ready to merge with optional follow-up enhancements. Nice work on the fix! The test-first approach and targeted solution demonstrate good engineering practices. |
Code ReviewGreat fix for issue #3410! The solution correctly identifies when measurement is needed for animations involving CSS variables. Here's my detailed feedback: ✅ Strengths
🔍 Observations & Suggestions1. Edge Case: Simple Value to Simple ValueLocation: The current logic only triggers measurement when
But what about:
This might be fine if the animation system can handle it, but worth considering if different CSS variables could cause issues. 2. Comment Stripping LogicLocation: The comment stripping uses // Current implementation
return value.split("/*")[0].includes("var(--")Potential issues:
Suggestion: Consider if the existing approach is sufficient or if a more robust regex would be better: return value.replace(/\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\//g, '').includes("var(--")However, for performance reasons and given the rarity of comments in animation values, the current simple approach is probably fine. 3. Test Comment AccuracyLocation: The test description says "ignores CSS variables in comments" but only tests the edge case where there's no actual test("detects CSS variables outside comments", () => {
expect(containsCSSVariable("var(--real) /* var(--commented) */")).toBe(true)
})This would verify the function works correctly when there ARE real variables mixed with commented ones. 4. Makefile ChangeLocation: The change to 🐛 Potential IssuesNone identified - the logic appears sound for the stated use case. ⚡ Performance Considerations
🔒 Security ConcernsNone - The code doesn't introduce any security vulnerabilities. It's purely internal logic for animation resolution. 📋 Test Coverage✅ Excellent:
🎯 Recommendations
SummaryThis is a solid, well-tested fix that correctly addresses the reported issue. The solution is minimal, focused, and doesn't over-engineer. The test coverage is thorough. I'd approve this PR with confidence. Rating: ✅ Approve with minor suggestions for consideration |
Code ReviewThank you for this fix! This PR properly addresses issue #3410 by ensuring animations from ✅ Strengths
🔍 Issues & Suggestions1. Redundant check in DOMKeyframesResolver.ts:97 (Minor)if (originHasVar !== targetHasVar && positionalValues[name]) {
this.needsMeasurement = true
return
}Issue: The Suggestion: The check is defensive but unnecessary. The logic is correct as-is, but could be simplified to: if (originHasVar !== targetHasVar) {
this.needsMeasurement = true
return
}This matches the pattern at line 122 where 2. Test timing could be more precise (Minor)// dev/react/src/tests/unit-conversion-var-to-simple.tsx:22
transition={{ duration: 0.05 }}
// packages/framer-motion/cypress/integration/unit-conversion.ts:18,23,28
.wait(200)The animation duration is 50ms but tests wait 200ms (4× longer). While this provides a safe buffer, consider:
3. Consider additional edge case tests (Enhancement)The current test covers the main case well. Consider adding tests for:
These would ensure the fix handles all variants of the bug. 4. containsCSSVariable could be more defensive (Very Minor)Current implementation: return value.split("/*")[0].includes("var(--")Edge case: Multi-line comments with Alternative (if being extra defensive): return value.replace(/\/\*[\s\S]*?\*\//g, '').includes("var(--")But the current implementation is likely fine for real-world usage. 🔒 Security & PerformanceSecurity: ✅ No concerns. String operations are safe, no injection vectors. Performance: ✅ Excellent. The 📋 Code Style Compliance✅ Follows CLAUDE.md conventions:
🎯 SummaryThis is a solid, well-tested fix that correctly handles the edge case where CSS variables in calc() expressions need measurement for proper interpolation. The implementation is clean and follows repository patterns. Minor suggestions:
Recommendation: ✅ Approve - The fix is correct and well-implemented. The suggestions above are minor optimizations that could be addressed in a follow-up if desired. Great work addressing this tricky animation edge case! 🚀 |
- Add roundtrip URL parameter to unit-conversion.tsx test for fast animations - Update Cypress test to verify 0 → calc(300px) → 0 animation completes correctly - Remove redundant unit-conversion-var-to-simple.tsx test file - Tests GitHub issue #3410 fix for animating between calc() with CSS vars and simple values 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code ReviewI've reviewed PR #3442 which fixes the issue of animating between ✅ Strengths
🔍 Observations & Suggestions1. Comment Stripping ConsistencyThe "100px /* comment */ var(--foo) /* another */" // Would incorrectly return trueSuggestion: While this edge case is unlikely in practice, consider documenting this limitation or using a more robust comment-stripping approach if this becomes an issue. 2. Performance ConsiderationThe new check at This is acceptable because:
3. Type SafetyThe Current behavior is fine - the type guard properly narrows to string checks. 4. Test CoverageThe E2E test is excellent, but consider adding a test case for:
Not blocking - current tests adequately verify the fix. 🐛 Potential IssuesMinor: Makefile Test Spec UpdateThe -test-single: build test-mkdir
-\tyarn start-server-and-test "yarn dev-server" http://localhost:9991 "cd packages/framer-motion && cypress run --config-file=cypress.react-19.json --headed --spec cypress/integration/layout-group.ts"
+test-single: build test-mkdir
+\tyarn start-server-and-test "yarn dev-server" http://localhost:9991 "cd packages/framer-motion && cypress run --config-file=cypress.react-19.json --headed --spec cypress/integration/unit-conversion.ts"Question: Should this Makefile change be committed, or is it just for development? If it's meant to stay, that's fine, but if it's accidental, it might confuse future developers about which test 🔒 SecurityNo security concerns. The change doesn't introduce any vulnerabilities:
📊 Overall AssessmentRecommendation: ✅ APPROVE This is a well-crafted fix that:
The only minor question is about the Makefile change - if that's intentional, this PR is ready to merge! Nice work 🎉 This fix will prevent a confusing animation bug that was preserving CSS variables incorrectly. |
- Use DOMMatrix to extract actual translateX value from computed style - More accurate than checking inline style string (which preserves calc expression) - Verifies the animation actually moves the element to the correct position 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pull Request ReviewThanks for this fix! The changes effectively address issue #3410 where animations between calc() values with CSS variables and simple values were incorrectly preserving the CSS variable structure. Positives
Suggestions
Security & PerformanceNo security concerns. The performance impact is negligible as the check only runs for positional values with exactly 2 keyframes. Overall: Approve with minor suggestions. Great work on fixing this tricky edge case! |
- Check computed transform matrix for actual translateX position - Verify style.transform preserves calc expression after first animation - Verify style.transform is "none" after animating back to 0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code ReviewThank you for this fix! I've reviewed the changes and they look solid. Here's my detailed feedback: ✅ Strengths
🔍 Detailed AnalysisCore Fix (DOMKeyframesResolver.ts:90-100)const originHasVar = containsCSSVariable(origin)
const targetHasVar = containsCSSVariable(target)
if (originHasVar \!== targetHasVar && positionalValues[name]) {
this.needsMeasurement = true
return
}Logic: When one keyframe contains a CSS var and the other doesn't, force measurement. This is correct because:
New Function (is-css-variable.ts:36-42)export function containsCSSVariable(
value?: AnyResolvedKeyframe | null
): boolean {
if (typeof value \!== "string") return false
return value.split("/*")[0].includes("var(--")
}Good:
Minor Consideration: The function uses E2E Test (unit-conversion.ts:7-44)The test properly validates:
Excellent: Uses 🎯 Minor Suggestions
if (originHasVar \!== targetHasVar && positionalValues[name]) {The
test("handles multiple var() instances", () => {
expect(containsCSSVariable("calc(var(--a) + var(--b))")).toBe(true)
})Note: This is already tested, so this is not critical.
🔒 Security & Performance
📝 Code Style ComplianceChecked against
✅ Final VerdictApproved - This is a high-quality fix that:
The implementation is correct and ready to merge. Great work! 🎉 |
Closes #3439
Fixes #3410