Skip to content

Commit fc097aa

Browse files
authored
Merge pull request technoph1le#78 from mayur1377/feature-framer
Feature : added some smooth framer animation
2 parents f1f3b6a + 1696e76 commit fc097aa

File tree

4 files changed

+115
-39
lines changed

4 files changed

+115
-39
lines changed

package-lock.json

Lines changed: 47 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"prepare": "husky"
1414
},
1515
"dependencies": {
16+
"framer-motion": "^11.15.0",
1617
"prismjs": "^1.29.0",
1718
"react": "^18.3.1",
1819
"react-dom": "^18.3.1",

src/components/SnippetList.tsx

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { motion, AnimatePresence } from "framer-motion";
12
import { useState } from "react";
23

34
import { useAppContext } from "@contexts/AppContext";
@@ -31,31 +32,55 @@ const SnippetList = () => {
3132

3233
return (
3334
<>
34-
<ul role="list" className="snippets">
35-
{fetchedSnippets.map((snippet, idx) => (
36-
<li key={idx}>
37-
<button
38-
className="snippet | flow"
39-
data-flow-space="sm"
40-
onClick={() => handleOpenModal(snippet)}
35+
<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+
}}
4157
>
42-
<div className="snippet__preview">
43-
<img src={language.icon} alt={language.lang} />
44-
</div>
45-
46-
<h3 className="snippet__title">{snippet.title}</h3>
47-
</button>
48-
</li>
49-
))}
50-
</ul>
51-
52-
{isModalOpen && snippet && (
53-
<SnippetModal
54-
snippet={snippet}
55-
handleCloseModal={handleCloseModal}
56-
language={language.lang}
57-
/>
58-
)}
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 }}
64+
>
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+
))}
72+
</AnimatePresence>
73+
</motion.ul>
74+
75+
<AnimatePresence mode="wait">
76+
{isModalOpen && snippet && (
77+
<SnippetModal
78+
snippet={snippet}
79+
handleCloseModal={handleCloseModal}
80+
language={language.lang}
81+
/>
82+
)}
83+
</AnimatePresence>
5984
</>
6085
);
6186
};

src/components/SnippetModal.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { motion } from "framer-motion";
12
import React from "react";
23
import ReactDOM from "react-dom";
34

@@ -29,15 +30,28 @@ const SnippetModal: React.FC<Props> = ({
2930
}
3031

3132
return ReactDOM.createPortal(
32-
<div
33+
<motion.div
34+
key="modal-overlay"
3335
className="modal-overlay"
3436
onClick={(e) => {
3537
if (e.target === e.currentTarget) {
3638
handleCloseModal();
3739
}
3840
}}
41+
initial={{ opacity: 0 }}
42+
animate={{ opacity: 1 }}
43+
exit={{ opacity: 0 }}
44+
transition={{ duration: 0.2 }}
3945
>
40-
<div className="modal | flow" data-flow-space="lg">
46+
<motion.div
47+
key="modal-content"
48+
className="modal | flow"
49+
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 }}
53+
transition={{ type: "spring", duration: 0.5 }}
54+
>
4155
<div className="modal__header">
4256
<h2 className="section-title">{snippet.title}</h2>
4357
<Button isIcon={true} onClick={handleCloseModal}>
@@ -67,8 +81,8 @@ const SnippetModal: React.FC<Props> = ({
6781
</li>
6882
))}
6983
</ul>
70-
</div>
71-
</div>,
84+
</motion.div>
85+
</motion.div>,
7286
modalRoot
7387
);
7488
};

0 commit comments

Comments
 (0)