fix(kanban-card): jumping hover animation & drag overlay consistency#324
fix(kanban-card): jumping hover animation & drag overlay consistency#324webdevcody merged 3 commits intoAutoMaker-Org:mainfrom
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughThe changes consolidate overlay rendering by replacing direct Card composition with the KanbanCard component for both normal and DragOverlay contexts, refactor the card's drag-and-drop from Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Board as KanbanBoard
participant DnD as DnDProvider/useDraggable
participant Card as KanbanCard
Note over User,Board: User starts drag on a card
User->>Card: pointerDown / initiate drag
Card->>DnD: register drag via useDraggable (start)
DnD-->>Board: emits dragging state / activeFeature
Board->>Card: render DragOverlay with `isOverlay=true` KanbanCard (wrapped, fixed width)
Note over Card: useLayoutEffect -> set isLifted for overlay visuals
Card->>User: visual lift + drag cursor + dndStyle applied
alt drop
DnD->>Card: end drag / drop
Card->>Board: update state (position/notify)
else cancel
DnD->>Card: cancel
Card->>Board: revert visuals
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
Comment |
Summary of ChangesHello @illia1f, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a visual regression in the Kanban board view where cards exhibited "jumping" or jittering animations during hover and drag-and-drop interactions. The core issue stemmed from a conflict between Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
The pull request refactors the KanbanCard component to switch from @dnd-kit/sortable's useSortable to @dnd-kit/core's useDraggable, introducing new helper functions for card border styling and cursor management. It also adds an isOverlay prop to the KanbanCard and implements a useLayoutEffect to manage a isLifted state, intended for animating the drag overlay. The KanbanBoard component is updated to render the KanbanCard directly within its DragOverlay, reusing the component for the dragged item's visual representation. A review comment points out that the wrapperClasses for the KanbanCard's drag overlay animation are missing Tailwind transition classes, causing an instant 'lift' effect instead of a smooth one, and suggests adding transition-transform duration-200 ease-out to fix this.
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/ui/src/components/views/board-view/kanban-board.tsx (1)
192-195: Consider removing unusedSortableContext.Since cards now use
useDraggableinstead ofuseSortable, theSortableContextwrapper no longer provides functional value. The PR notes that in-column reordering is not implemented yet, so this could be cleaned up now or kept as scaffolding for future reordering support.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsxapps/ui/src/components/views/board-view/kanban-board.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always import from shared packages (@automaker/*), never from old relative paths
Files:
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsxapps/ui/src/components/views/board-view/kanban-board.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
resolveModelString()from @automaker/model-resolver to convert model aliases (haiku, sonnet, opus) to full model names
Files:
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsxapps/ui/src/components/views/board-view/kanban-board.tsx
🧬 Code graph analysis (2)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (2)
apps/ui/src/lib/utils.ts (1)
cn(5-7)apps/ui/src/components/ui/card.tsx (1)
Card(84-84)
apps/ui/src/components/views/board-view/kanban-board.tsx (1)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (1)
KanbanCard(59-222)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: e2e
🔇 Additional comments (5)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (4)
1-2: LGTM!The switch from
useSortabletouseDraggablealigns with the PR objective of removing reordering behavior that caused animation conflicts. The additional React hooks for managing the lift animation are appropriate.
12-29: LGTM!Clean extraction of styling logic into helper functions.
getCardBorderStylehandles border opacity mixing well, andgetCursorClassprovides clear cursor feedback based on component state.
89-95: LGTM!Using
useLayoutEffectwithrequestAnimationFrameis a valid pattern to defer the lift animation until after the overlay is painted, ensuring a smooth visual transition.
206-221: LGTM!The multi-layered structure cleanly separates dnd-kit registration (outer wrapper with
ref,attributes,listeners) from the inner card's visual styling and transitions. Conditionally spreading listeners only when draggable is a good safeguard.apps/ui/src/components/views/board-view/kanban-board.tsx (1)
243-268: LGTM!Good improvement to render
KanbanCardwithisOverlayprop in theDragOverlayinstead of a separate Card-based composition. This ensures visual consistency between the dragged card and in-place cards. The fixed width wrapper maintains proper sizing, and empty stub handlers are appropriate since the overlay is non-interactive.
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
Show resolved
Hide resolved
…r smoother animations
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (1)
89-95: Add cleanup to prevent potential setState warning.The
requestAnimationFramecallback could fire after the component unmounts, causing a React warning about setting state on an unmounted component. While unlikely in practice (the DragOverlay typically stays mounted), adding cleanup improves defensive coding.🔎 Proposed defensive cleanup
useLayoutEffect(() => { if (isOverlay) { - requestAnimationFrame(() => { + const rafId = requestAnimationFrame(() => { setIsLifted(true); }); + return () => cancelAnimationFrame(rafId); } }, [isOverlay]);
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always import from shared packages (@automaker/*), never from old relative paths
Files:
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
resolveModelString()from @automaker/model-resolver to convert model aliases (haiku, sonnet, opus) to full model names
Files:
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-30T01:02:07.114Z
Learnt from: illia1f
Repo: AutoMaker-Org/automaker PR: 324
File: apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx:122-131
Timestamp: 2025-12-30T01:02:07.114Z
Learning: Tailwind CSS v4 uses postfix syntax for the important modifier: append ! at the end of the utility class (e.g., backdrop-blur-[0px]! or hover:bg-red-500!). The older v3 style used a prefix (!) at the start (e.g., !backdrop-blur-[0px]); prefer the postfix form for consistency across TSX files.
Applied to files:
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: e2e
🔇 Additional comments (6)
apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (6)
12-29: LGTM! Clean helper functions.Both
getCardBorderStyleandgetCursorClassare well-structured pure functions with clear logic and proper typing. The border style computation correctly handles the enabled/opacity cases, and the cursor states appropriately reflect the drag interaction model.
56-56: LGTM! Appropriate API extension.The
isOverlayoptional prop correctly extends the component API to support overlay-specific behavior, aligning with the PR's drag-and-drop refactoring objectives.
107-109: LGTM! Correct dndStyle simplification.Removing
transformandtransitionfromdndStyleand keeping onlyopacitycorrectly addresses the PR's core issue—eliminating the conflict between dnd-kit's reordering logic and Tailwind hover transforms that caused jitter.
113-117: LGTM! Complete transition classes present.The
wrapperClassescorrectly includestransition-transform duration-200 ease-out, which will smoothly animate the scale and rotation whenisLiftedbecomes true. This addresses the concern from the previous review about missing transition properties.
206-221: LGTM! Clean separation of concerns.The wrapper structure correctly separates dnd-kit integration (outer
divwith ref, attributes, and conditional listeners) from the card's visual styling (inner content). The conditional listener spreading at line 211 adds a defensive layer ensuring overlay cards can't be directly dragged, complementing thedisabledprop.
1-10: The imports in kanban-card.tsx comply with coding guidelines. The guideline specifies "never from old relative paths," which refers to imports like../../../lib/utils. The current code uses@/path aliases (mapped to./src/*in tsconfig.json), which is the established pattern throughout the apps/ui codebase. No@automaker/*alternatives exist for these app-internal modules (lib/utils,components/ui/card,store/app-store), which are consistently imported via@/across 15+ files in the application.
Summary
This PR fixes a visual regression in the Board view where Kanban cards would "jump" or jitter during hover animations and drag-and-drop interactions.
The Problem
The issue was caused by a conflict between dnd-kit's reordering logic and Tailwind CSS hover transforms. Using useSortable introduced automatic layout calculations and transitions
that competed with the card's hover lift effect (hover:-translate-y-0.5), leading to "snapping" and visual instability.
The Solution
useDraggable: Since card reordering within columns is not yet implemented, we refactored KanbanCard to use useDraggable instead of useSortable. This removes thecomplex reordering logic that was the primary source of the jitter.
completely eliminating transform conflicts.
layout stays perfectly stable.
Impact
Screenshots
Before
After
Testing
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.