Created
May 30, 2024 13:57
-
-
Save vitalijalbu/f94a4907626d6511025c12d15513580d to your computer and use it in GitHub Desktop.
ReactJS - Native Toast DOM (no components imported)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "./styles.css"; | |
import useToast from "./useToast"; | |
export default function App() { | |
const showToast = useToast(); | |
const handleClick = () => { | |
showToast({ | |
title: "Account created.", | |
description: "We've created your account for you.", | |
status: "success", | |
duration: 2000, | |
isClosable: true, | |
}); | |
}; | |
return ( | |
<div className="App"> | |
<h1>Hello CodeSandbox</h1> | |
<h2>Start editing to see some magic happen!</h2> | |
<button onClick={handleClick}>Show Toast</button> | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#toast-root { | |
position: fixed; | |
top: 20px; | |
right: 20px; | |
z-index: 9999; | |
} | |
.toast { | |
background: white; | |
border: 1px solid #ccc; | |
padding: 10px; | |
margin-bottom: 10px; | |
border-radius: 5px; | |
opacity: 0; | |
animation: fadein 0.5s forwards; | |
} | |
.toast.success { | |
border-color: green; | |
} | |
.toast button { | |
background: none; | |
border: none; | |
color: blue; | |
cursor: pointer; | |
} | |
@keyframes fadein { | |
from { | |
opacity: 0; | |
} | |
to { | |
opacity: 1; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const toastRoot = document.createElement("div"); | |
toastRoot.id = "toast-root"; | |
document.body.appendChild(toastRoot); | |
const createToast = ({ title, description, status, isClosable, duration }) => { | |
const toastElement = document.createElement("div"); | |
toastElement.className = `toast ${status}`; | |
toastElement.innerHTML = ` | |
<strong>${title}</strong> | |
<p>${description}</p> | |
${isClosable ? '<button class="toast-close">Close</button>' : ""} | |
`; | |
return toastElement; | |
}; | |
const useToast = () => { | |
return ({ | |
title, | |
description, | |
status, | |
duration = 5000, | |
isClosable = true, | |
}) => { | |
const id = Date.now(); | |
const toastElement = createToast({ | |
title, | |
description, | |
status, | |
isClosable, | |
duration, | |
onClose: () => removeToast(id), | |
}); | |
const removeToast = () => { | |
if (toastElement) { | |
toastElement.remove(); | |
} | |
}; | |
if (isClosable) { | |
toastElement | |
.querySelector(".toast-close") | |
.addEventListener("click", removeToast); | |
} | |
toastRoot.appendChild(toastElement); | |
setTimeout(() => removeToast(), duration); | |
}; | |
}; | |
export default useToast; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment