Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions frontend/src/components/layout/MoreDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,25 @@ export function MoreDrawer({ open, onClose }: Readonly<MoreDrawerProps>) {
const isAdmin = useAdminStore((s) => s.isAdmin);
const drawerRef = useRef<HTMLDialogElement>(null);
const [animating, setAnimating] = useState(false);
const [prevOpen, setPrevOpen] = useState(open);
const touchStartY = useRef(0);
const touchDeltaY = useRef(0);

// Track mount animation
// Reset animation immediately when the drawer closes — done during render
// (https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes)
// rather than in an effect to satisfy react-hooks/set-state-in-effect.
if (open !== prevOpen) {
setPrevOpen(open);
if (!open) setAnimating(false);
}

// Defer enabling the animation class to the next frame so CSS transitions
// run from the closed state. setState inside requestAnimationFrame is
// asynchronous, so it does not violate set-state-in-effect.
useEffect(() => {
if (open) {
requestAnimationFrame(() => setAnimating(true));
} else {
setAnimating(false);
}
if (!open) return;
const id = requestAnimationFrame(() => setAnimating(true));
return () => cancelAnimationFrame(id);
}, [open]);
Comment on lines +99 to 114
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new open/close animation sequencing logic (render-phase reset via prevOpen and deferred setAnimating(true) via requestAnimationFrame) isn’t covered by tests. Consider adding a regression test that toggles open (using rerender) and asserts the drawer/backdrop classes start in the non-animating state and only flip after the rAF callback runs (and that a close transition resets the animation state before the next open).

Copilot uses AI. Check for mistakes.

// Close on Escape
Expand Down
Loading