[refactor] extract Expander animation logic into useDetailsAnimation hook#13933
Conversation
✅ PR preview is ready!
|
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
SummaryThis PR refactors the Expander component by extracting its animation logic into two new modules:
The Code QualityThe refactoring is well-structured and follows the project's coding conventions:
Minor observation (not a blocker): The Behavioral equivalence note: I verified the Test CoverageNew unit tests are comprehensive:
Existing tests are unaffected:
One area for potential improvement (non-blocking): The Backwards CompatibilityNo breaking changes. This is a purely internal refactoring:
Security & RiskNo security concerns. This is a frontend-only refactoring with no changes to data handling, network communication, or authentication. The risk of regression is low due to:
AccessibilityNo accessibility impact. The refactoring preserves all existing accessibility features:
Recommendations
VerdictAPPROVED: Clean, well-tested refactoring that extracts Expander animation logic into a reusable hook and utility with no behavioral changes, improved documentation, and proper cleanup. This is an automated AI review by |
87f055d to
95741ad
Compare
| } | ||
|
|
||
| const contentHeight = | ||
| // eslint-disable-next-line streamlit-custom/no-force-reflow-access -- Need content height to calculate animation end value |
There was a problem hiding this comment.
This follows the original implementation.
95741ad to
13ec12f
Compare
This seems better to address in the next PR where the behaviour is changed. |
There was a problem hiding this comment.
Pull request overview
This PR refactors the Expander component by extracting the <details> element animation logic into a reusable custom hook (useDetailsAnimation) and a standalone animation utility (animateHeight). This improves code organization, testability, and reusability while preserving the original functionality including the Safari repaint workaround.
Changes:
- Extracted animation state management and toggle logic into
useDetailsAnimationhook - Created
animateHeightutility wrapping Web Animations API with proper lifecycle handling - Added comprehensive unit tests for both the hook and utility
- Updated vitest mock to include
cancelmethod for animation objects
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/lib/src/components/elements/Expander/useDetailsAnimation.ts | New hook managing open state, backend sync, animation refs, and toggle handler with Safari workaround |
| frontend/lib/src/components/elements/Expander/useDetailsAnimation.test.ts | Comprehensive tests for hook behavior including state transitions, backend sync, and cleanup |
| frontend/lib/src/components/elements/Expander/animateHeight.ts | Reusable animation utility with cancel support and distinct finish/cancel cleanup semantics |
| frontend/lib/src/components/elements/Expander/animateHeight.test.ts | Tests for animation creation, lifecycle, and promise resolution |
| frontend/lib/src/components/elements/Expander/Expander.tsx | Refactored to use new hook, removing ~120 lines of animation logic |
| frontend/vitest.setup.ts | Added cancel method to animation mock for new utility |
📈 Frontend coverage change detectedThe frontend unit test (vitest) coverage has increased by 0.0700%
🎉 Great job on improving test coverage! |
13ec12f to
66563b6
Compare
66563b6 to
8bbe616
Compare
…hook (#13933) ## Describe your changes Extracts the `<details>` open/close animation logic from `Expander.tsx` into a reusable `useDetailsAnimation` hook and a standalone `animateHeight` utility. - `useDetailsAnimation` manages open state, backend sync, and the toggle animation (including the Safari two-step repaint workaround) - `animateHeight` wraps the Web Animations API with a cancellable `AnimationHandle` that distinguishes finish vs cancel cleanup semantics ## Testing Plan - [x] Unit Tests (JS) - `useDetailsAnimation.test.ts` — initial state, toggle behavior, backend sync, label-based reset, cleanup - `animateHeight.test.ts` — animation creation, custom options, finish/cancel lifecycle, promise resolution

Describe your changes
Extracts the
<details>open/close animation logic fromExpander.tsxinto a reusableuseDetailsAnimationhook and a standaloneanimateHeightutility.useDetailsAnimationmanages open state, backend sync, and the toggle animation (including the Safari two-step repaint workaround)animateHeightwraps the Web Animations API with a cancellableAnimationHandlethat distinguishes finish vs cancel cleanup semanticsTesting Plan
useDetailsAnimation.test.ts— initial state, toggle behavior, backend sync, label-based reset, cleanupanimateHeight.test.ts— animation creation, custom options, finish/cancel lifecycle, promise resolution