Skip to content

Commit 322e691

Browse files
committed
feat: contact modal animation
1 parent 64a715d commit 322e691

File tree

2 files changed

+69
-5
lines changed

2 files changed

+69
-5
lines changed

src/components/ContactModal.css

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
2+
@keyframes fadeIn {
3+
from { opacity: 0; }
4+
to { opacity: 1; }
5+
}
6+
7+
@keyframes fadeOut {
8+
from { opacity: 1; }
9+
to { opacity: 0; }
10+
}
11+
12+
@keyframes slideUp {
13+
from { transform: translateY(20px); opacity: 0; }
14+
to { transform: translateY(0); opacity: 1; }
15+
}
16+
17+
@keyframes slideDown {
18+
from { transform: translateY(0); opacity: 1; }
19+
to { transform: translateY(20px); opacity: 0; }
20+
}
21+
122
.modal-overlay {
223
position: fixed;
324
top: 0;
@@ -10,6 +31,8 @@
1031
justify-content: center;
1132
align-items: center;
1233
z-index: 1000;
34+
animation-duration: 0.3s;
35+
animation-fill-mode: forwards;
1336
}
1437

1538
.modal-content {
@@ -25,6 +48,24 @@
2548
box-shadow: inset 0 0 0 4px #4a5568; /* Inner border */
2649
font-family: 'Arvo', serif;
2750
font-weight: 300;
51+
animation-duration: 0.3s;
52+
animation-fill-mode: forwards;
53+
}
54+
55+
.modal-overlay.fade-in {
56+
animation-name: fadeIn;
57+
}
58+
59+
.modal-overlay.fade-out {
60+
animation-name: fadeOut;
61+
}
62+
63+
.modal-content.slide-up {
64+
animation-name: slideUp;
65+
}
66+
67+
.modal-content.slide-down {
68+
animation-name: slideDown;
2869
}
2970

3071
.modal-header {
@@ -77,3 +118,4 @@
77118
.red-text {
78119
color: #f87171;
79120
}
121+

src/components/ContactModal.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import './ContactModal.css';
3-
import {X, Envelope, LinkedinLogo, TwitterLogo} from '@phosphor-icons/react';
3+
import { X, Envelope, LinkedinLogo, TwitterLogo } from '@phosphor-icons/react';
44

55
const colorizeText = (text) => {
66
return text.split(' ').map((word, index) => {
@@ -13,16 +13,38 @@ const colorizeText = (text) => {
1313
};
1414

1515
const ContactModal = ({ isOpen, onClose }) => {
16+
const [isClosing, setIsClosing] = useState(false);
17+
18+
useEffect(() => {
19+
if (!isOpen) {
20+
setIsClosing(false);
21+
}
22+
}, [isOpen]);
23+
24+
const handleClose = () => {
25+
setIsClosing(true);
26+
setTimeout(() => {
27+
onClose();
28+
setIsClosing(false);
29+
}, 300); // Corresponds to animation duration
30+
};
31+
1632
if (!isOpen) {
1733
return null;
1834
}
1935

2036
return (
21-
<div className="modal-overlay" onClick={onClose}>
22-
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
37+
<div
38+
className={`modal-overlay ${isOpen && !isClosing ? 'fade-in' : 'fade-out'}`}
39+
onClick={handleClose}
40+
>
41+
<div
42+
className={`modal-content ${isOpen && !isClosing ? 'slide-up' : 'slide-down'}`}
43+
onClick={(e) => e.stopPropagation()}
44+
>
2345
<div className="modal-header">
2446
<h2>{colorizeText('Contact Me')}</h2>
25-
<button onClick={onClose} className="close-button">
47+
<button onClick={handleClose} className="close-button">
2648
<X size={24} />
2749
</button>
2850
</div>

0 commit comments

Comments
 (0)