Skip to content

Commit 14b3891

Browse files
committed
smoothed modal and list items animations
1 parent 2917bb7 commit 14b3891

File tree

3 files changed

+49
-38
lines changed

3 files changed

+49
-38
lines changed

src/components/SnippetList.tsx

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,42 +33,54 @@ const SnippetList = () => {
3333
return (
3434
<>
3535
<motion.ul role="list" className="snippets">
36-
<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 }}
36+
<AnimatePresence mode="popLayout" presenceAffectsLayout>
37+
{fetchedSnippets.map((currentSnippet, idx) => {
38+
return (
39+
<motion.li
40+
key={currentSnippet.title + idx}
41+
initial={{ opacity: 0, y: 20 }}
42+
layoutId={currentSnippet.title + (idx + 1).toString()}
43+
animate={{
44+
opacity: 1,
45+
y: 0,
46+
transition: {
47+
delay: 0.09 + idx * 0.05,
48+
duration: 0.2,
49+
},
50+
}}
51+
exit={{
52+
opacity: 0,
53+
y: -20,
54+
transition: {
55+
delay: idx * 0.01,
56+
duration: 0.09,
57+
},
58+
}}
59+
transition={{
60+
type: "spring",
61+
duration: 0.5,
62+
}}
6463
>
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-
))}
64+
<motion.button
65+
className="snippet | flow"
66+
data-flow-space="sm"
67+
onClick={() =>
68+
handleOpenModal({
69+
...currentSnippet,
70+
idx: idx + 1,
71+
})
72+
}
73+
whileHover={{ scale: 1.01 }}
74+
whileTap={{ scale: 0.98 }}
75+
>
76+
<div className="snippet__preview">
77+
<img src={language.icon} alt={language.lang} />
78+
</div>
79+
<h3 className="snippet__title">{currentSnippet.title}</h3>
80+
</motion.button>
81+
</motion.li>
82+
);
83+
})}
7284
</AnimatePresence>
7385
</motion.ul>
7486

src/components/SnippetModal.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ const SnippetModal: React.FC<Props> = ({
4747
key="modal-content"
4848
className="modal | flow"
4949
data-flow-space="lg"
50-
initial={{ scale: 0.8, opacity: 0, y: 20 }}
51-
animate={{ scale: 1, opacity: 1, y: 0 }}
52-
exit={{ scale: 0.8, opacity: 0, y: 20 }}
50+
layoutId={snippet.title + snippet.idx?.toString()}
5351
transition={{ type: "spring", duration: 0.5 }}
5452
>
5553
<div className="modal__header">

src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type SnippetType = {
1414
code: string;
1515
tags: string[];
1616
author: string;
17+
idx?: number; // Add optional idx property
1718
};
1819

1920
export type AppState = {

0 commit comments

Comments
 (0)