refactor: extract reusable utilities and simplify logic#75
Conversation
📝 WalkthroughWalkthroughExtracts and centralizes internal utilities and refactors animation logic: adds a reusable Changes
Sequence Diagram(s)(omitted — changes are refactors and a utility addition; no multi-component control flow requiring diagram) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @src/hooks/useResolvedMotion/useResolvedMotion.ts:
- Line 28: The call to mergePresets inside useResolvedMotion occurs before the
const arrow mergePresets is declared, causing a Temporal Dead Zone error; fix it
by moving the mergePresets declaration above the useResolvedMotion hook (or
convert mergePresets to a hoisted function declaration) so mergePresets is
defined before being called, ensuring the useResolvedMotion function can call
mergePresets without runtime ReferenceError.
In @src/utils/countNodes/countNodes.spec.tsx:
- Around line 87-90: The test under getNodes/countNodes is misnamed or has the
wrong expectation: the spec "should return 0 for an empty array" calls
getNodes(<></>) and expects countNodes(nodes) toBe(1); change the expectation to
0 (or update the test name if 1 was intentional). Locate the test case
referencing getNodes and countNodes in src/utils/countNodes/countNodes.spec.tsx
and set expect(countNodes(nodes)).toBe(0) to match an empty fragment producing
an empty array.
🧹 Nitpick comments (1)
src/hooks/useResolvedMotion/useResolvedMotion.spec.ts (1)
41-49: Good test coverage for the new merging behavior.The test validates that multiple presets are correctly merged into a single motion configuration. This aligns well with the
mergePresetshelper introduction.Consider adding an edge case test for overlapping presets (e.g.,
['fade-in', 'fade-out']) to document the expected overwrite behavior.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/hooks/useAnimatedChildren/useAnimatedChildren.tsxsrc/hooks/useResolvedMotion/useResolvedMotion.spec.tssrc/hooks/useResolvedMotion/useResolvedMotion.tssrc/types/animations.tssrc/utils/countNodes/countNodes.spec.tsxsrc/utils/countNodes/countNodes.tssrc/utils/countNodes/index.tssrc/utils/generateAnimation/generateAnimation.ts
🧰 Additional context used
🧬 Code graph analysis (4)
src/utils/countNodes/countNodes.ts (1)
src/utils/typeGuards/typeGuards.ts (2)
isNullishNode(21-23)isElementWithChildren(32-39)
src/utils/countNodes/countNodes.spec.tsx (1)
src/utils/countNodes/countNodes.ts (1)
countNodes(13-29)
src/utils/generateAnimation/generateAnimation.ts (2)
src/constants/animationDefaults.ts (1)
ANIMATION_DEFAULTS(19-22)src/types/animations.ts (2)
CustomAnimation(141-143)StandardAnimation(123-130)
src/hooks/useResolvedMotion/useResolvedMotion.ts (3)
src/types/common.ts (2)
Preset(67-83)Motion(51-60)src/hooks/useResolvedMotion/motionMap.ts (1)
motionMap(6-23)src/hooks/useResolvedMotion/index.ts (1)
motionMap(1-1)
🔇 Additional comments (9)
src/types/animations.ts (1)
119-131: LGTM!The
StandardAnimationunion type is a clean abstraction that consolidates all standard animation types. This improves type safety ingenerateAnimation.tsand makes the animation type hierarchy more explicit.src/hooks/useResolvedMotion/useResolvedMotion.ts (1)
41-45: Helper logic is correct.The
mergePresetsimplementation cleanly combines preset configurations. Note that if multiple presets define the same animation type (e.g., two presets both definingfade), the later preset will overwrite the earlier one—this appears to be the intended behavior based on the reduce pattern.src/utils/generateAnimation/generateAnimation.ts (3)
26-45: Clean refactor to processor-based architecture.The decomposition into
processStandardAnimationandprocessCustomAnimationmakes the animation type handling explicit and easier to extend. TheforEachloop with early return for null/undefined is cleaner than the previous reduce-based approach.
50-69: Well-structured standard animation processor.The logic correctly extracts animation parameters, calculates timing, and generates both the animation string and CSS custom properties. The separation of concerns makes unit testing and future modifications straightforward.
71-81: Consistent interface with standard processor.Returning an empty
customPropsobject maintains a uniform return shape across both processors, which simplifies the calling code and supports future extensibility if custom animations need CSS properties.src/utils/countNodes/index.ts (1)
1-1: LGTM!Clean barrel export for the new
countNodesutility. This establishes a clear public API for the extracted utility.src/hooks/useAnimatedChildren/useAnimatedChildren.tsx (1)
5-5: LGTM! Clean extraction of node counting logic.The import change correctly sources
countNodesfrom the new centralized utility, aligning with the PR's goal of improving reusability. The function signature and usage remain consistent.src/utils/countNodes/countNodes.ts (1)
13-29: Clean, well-documented utility function.The implementation correctly:
- Iterates using
Children.forEachfor proper ReactNode handling- Skips nullish nodes appropriately
- Counts both parent elements and recursively traverses their children
- Returns the total count as a pure function
The logic properly counts each non-nullish node once, including both container elements and their nested children, which matches the animation sequencing requirements in
useAnimatedChildren.src/utils/countNodes/countNodes.spec.tsx (1)
5-132: Comprehensive test coverage for the utility.The test suite covers a good range of scenarios:
- Simple text and element nodes
- Nested and deeply nested structures
- Mixed content
- Arrays and null/undefined handling
- Functional component children
- Complex real-world structures
This provides solid confidence in the
countNodesutility's correctness.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Description
This PR completes refactoring, focusing on improving reusability and reducing function complexity across core animation logic.
Utility extraction & reuse
countNodesinto a standalone, reusable utility.useResolvedMotionby extractingmergePresetsinto a dedicated helper function.Function complexity reduction
generateAnimationby splitting its logic into:processStandardAnimationprocessCustomAnimationType of change
Checklist
Summary by CodeRabbit
New Features
Tests
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.