1
- import { motion , AnimatePresence } from "framer- motion" ;
1
+ import { motion , AnimatePresence , useReducedMotion } from "motion/react " ;
2
2
import { useState } from "react" ;
3
3
4
4
import { useAppContext } from "@contexts/AppContext" ;
@@ -13,6 +13,8 @@ const SnippetList = () => {
13
13
const { fetchedSnippets } = useSnippets ( ) ;
14
14
const [ isModalOpen , setIsModalOpen ] = useState ( false ) ;
15
15
16
+ const shouldReduceMotion = useReducedMotion ( ) ;
17
+
16
18
if ( ! fetchedSnippets )
17
19
return (
18
20
< div >
@@ -34,41 +36,49 @@ const SnippetList = () => {
34
36
< >
35
37
< motion . ul role = "list" className = "snippets" >
36
38
< AnimatePresence mode = "popLayout" >
37
- { fetchedSnippets . map ( ( snippet , idx ) => (
38
- < motion . li
39
- key = { idx }
40
- initial = { { opacity : 0 , y : 20 } }
41
- animate = { {
42
- opacity : 1 ,
43
- y : 0 ,
44
- transition : {
45
- delay : idx * 0.05 ,
46
- duration : 0.2 ,
47
- } ,
48
- } }
49
- exit = { {
50
- opacity : 0 ,
51
- y : - 20 ,
52
- transition : {
53
- delay : ( fetchedSnippets . length - 1 - idx ) * 0.01 ,
54
- duration : 0.09 ,
55
- } ,
56
- } }
57
- >
58
- < motion . button
59
- className = "snippet | flow"
60
- data-flow-space = "sm"
61
- onClick = { ( ) => handleOpenModal ( snippet ) }
62
- whileHover = { { scale : 1.01 } }
63
- whileTap = { { scale : 0.98 } }
39
+ { fetchedSnippets . map ( ( snippet , idx ) => {
40
+ const uniqueId = ` ${ language . lang } - ${ snippet . title } ` ;
41
+ return (
42
+ < motion . li
43
+ key = { uniqueId }
44
+ layoutId = { uniqueId }
45
+ initial = { { opacity : 0 , y : 20 } }
46
+ animate = { {
47
+ opacity : 1 ,
48
+ y : 0 ,
49
+ transition : {
50
+ delay : shouldReduceMotion ? 0 : 0.09 + idx * 0.05 ,
51
+ duration : shouldReduceMotion ? 0 : 0.2 ,
52
+ } ,
53
+ } }
54
+ exit = { {
55
+ opacity : 0 ,
56
+ y : - 20 ,
57
+ transition : {
58
+ delay : idx * 0.01 ,
59
+ duration : shouldReduceMotion ? 0 : 0.09 ,
60
+ } ,
61
+ } }
62
+ transition = { {
63
+ ease : [ 0 , 0.75 , 0.25 , 1 ] ,
64
+ duration : shouldReduceMotion ? 0 : 0.25 ,
65
+ } }
64
66
>
65
- < div className = "snippet__preview" >
66
- < img src = { language . icon } alt = { language . lang } />
67
- </ div >
68
- < h3 className = "snippet__title" > { snippet . title } </ h3 >
69
- </ motion . button >
70
- </ motion . li >
71
- ) ) }
67
+ < motion . button
68
+ className = "snippet | flow"
69
+ data-flow-space = "sm"
70
+ onClick = { ( ) => handleOpenModal ( snippet ) }
71
+ whileHover = { { scale : 1.01 } }
72
+ whileTap = { { scale : 0.98 } }
73
+ >
74
+ < div className = "snippet__preview" >
75
+ < img src = { language . icon } alt = { language . lang } />
76
+ </ div >
77
+ < h3 className = "snippet__title" > { snippet . title } </ h3 >
78
+ </ motion . button >
79
+ </ motion . li >
80
+ ) ;
81
+ } ) }
72
82
</ AnimatePresence >
73
83
</ motion . ul >
74
84
0 commit comments