feat: migrate to motion and fix some animations

This commit is contained in:
MAZE 2025-08-06 13:07:03 +03:30
parent 81d9d7ca03
commit b191e6067d
13 changed files with 96 additions and 28 deletions

69
package-lock.json generated
View file

@ -25,6 +25,7 @@
"framer-motion": "10.16.4",
"howler": "2.2.4",
"js-confetti": "0.12.0",
"motion": "12.23.12",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "3.2.1",
@ -20732,6 +20733,74 @@
"node": ">=0.10.0"
}
},
"node_modules/motion": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/motion/-/motion-12.23.12.tgz",
"integrity": "sha512-8jCD8uW5GD1csOoqh1WhH1A6j5APHVE15nuBkFeRiMzYBdRwyAHmSP/oXSuW0WJPZRXTFdBoG4hY9TFWNhhwng==",
"license": "MIT",
"dependencies": {
"framer-motion": "^12.23.12",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/motion-dom": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.12.tgz",
"integrity": "sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.23.6"
}
},
"node_modules/motion-utils": {
"version": "12.23.6",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
"integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
"license": "MIT"
},
"node_modules/motion/node_modules/framer-motion": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.12.tgz",
"integrity": "sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.23.12",
"motion-utils": "^12.23.6",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/mrmime": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",

View file

@ -41,6 +41,7 @@
"framer-motion": "10.16.4",
"howler": "2.2.4",
"js-confetti": "0.12.0",
"motion": "12.23.12",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "3.2.1",

View file

@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { BiUndo, BiTrash } from 'react-icons/bi/index';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion } from 'motion/react';
import { useHotkeys } from 'react-hotkeys-hook';
import { Tooltip } from '@/components/tooltip';

View file

@ -1,4 +1,4 @@
import { AnimatePresence } from 'framer-motion';
import { AnimatePresence } from 'motion/react';
import { Category } from './category';
import { Donate } from './donate';

View file

@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion } from 'motion/react';
import { IoClose } from 'react-icons/io5/index';
import FocusTrap from 'focus-trap-react';

View file

@ -1,5 +1,5 @@
import { useState, useEffect, useMemo, useCallback } from 'react';
import { motion } from 'framer-motion';
import { motion } from 'motion/react';
import { padNumber } from '@/helpers/number';

View file

@ -1,4 +1,4 @@
import { motion } from 'framer-motion';
import { motion } from 'motion/react';
import { mix, fade, slideY } from '@/lib/motion';

View file

@ -1,5 +1,5 @@
import { BiHeart, BiSolidHeart } from 'react-icons/bi/index';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion } from 'motion/react';
import { useSoundStore } from '@/stores/sound';
import { cn } from '@/helpers/styles';

View file

@ -1,5 +1,5 @@
import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion } from 'motion/react';
import { Sound } from './sound';
import { useLocalStorage } from '@/hooks/use-local-storage';

View file

@ -2,7 +2,7 @@ import { useState, useMemo, useCallback } from 'react';
import { IoMenu, IoClose } from 'react-icons/io5/index';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { useHotkeys } from 'react-hotkeys-hook';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion } from 'motion/react';
import {
ShuffleItem,

View file

@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import { BiUpArrowAlt } from 'react-icons/bi/index';
import { motion, AnimatePresence } from 'framer-motion';
import { motion } from 'motion/react';
import { mix, fade, slideY } from '@/lib/motion';
@ -30,22 +30,20 @@ export function ScrollToTop() {
const variants = mix(fade(), slideY(10, 0));
return (
<AnimatePresence>
{isVisible ? (
<motion.button
animate="show"
aria-label="Scroll to top"
className={styles.button}
exit="hidden"
initial="hidden"
variants={variants}
onClick={scrollToTop}
>
<BiUpArrowAlt />
</motion.button>
) : (
<div />
)}
</AnimatePresence>
<motion.button
animate={isVisible ? 'show' : 'hidden'}
aria-label="Scroll to top"
className={styles.button}
exit="hidden"
initial="hidden"
variants={variants}
style={{
pointerEvents: isVisible ? 'auto' : 'none',
visibility: isVisible ? 'visible' : 'hidden',
}}
onClick={scrollToTop}
>
<BiUpArrowAlt />
</motion.button>
);
}

View file

@ -1,5 +1,5 @@
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { motion, AnimatePresence } from 'motion/react';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import { slideX, slideY, mix, fade } from '@/lib/motion';

View file

@ -5,7 +5,7 @@ import {
useRef,
useContext,
} from 'react';
import { AnimatePresence } from 'framer-motion';
import { AnimatePresence } from 'motion/react';
import { Snackbar } from '@/components/snackbar';