Skip to content
This repository has been archived by the owner on Dec 2, 2022. It is now read-only.

Commit

Permalink
feat: add animations & timeouts to toasts
Browse files Browse the repository at this point in the history
  • Loading branch information
Ovyerus committed Jun 6, 2021
1 parent b48c39c commit 0001954
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 22 deletions.
56 changes: 41 additions & 15 deletions components/Toast.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,52 @@
import close from "@iconify/icons-gg/close";
import { Icon } from "@iconify/react";
import cc from "classcat";
import React from "react";
import { motion } from "framer-motion";
import React, { useEffect } from "react";

const Toast = ({ children, className, onClose }: ToastProps) => (
<div
role="status"
className={cc([
"bg-white sm:max-w-sm w-full p-4 flex items-center leading-tight rounded-xl shadow-xl",
className,
])}
>
<div className="w-full flex-grow">{children}</div>
<button className="rounded-button" onClick={() => onClose()}>
<Icon icon={close} />
</button>
</div>
);
const Toast = ({ children, className, duration, onClose }: ToastProps) => {
// TODO: useReducedMotion

useEffect(() => {
if (!duration) return;

const timeout = setTimeout(() => onClose(), duration);
return () => clearTimeout(timeout);
}, []);

return (
<motion.div
role="status"
className={cc([
"bg-white dark:bg-black dark:text-white sm:max-w-sm w-full p-4 flex items-center leading-tight rounded-xl shadow-xl",
className,
])}
// Can't use percentage values here, otherwise we get a layout jump :s
// https://github.com/framer/motion/issues/648
initial={{ opacity: 0, x: 500 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 500 }}
transition={{
type: "spring",
mass: 0.25,
damping: 10,
stiffness: 100,
velocity: 2,
}}
layout
>
<div className="w-full flex-grow">{children}</div>
<button className="rounded-button" onClick={() => onClose()}>
<Icon icon={close} />
</button>
</motion.div>
);
};

export interface ToastProps {
children: React.ReactNode;
className?: string;
duration: number;
onClose(): void;
}

Expand Down
16 changes: 9 additions & 7 deletions components/Toasts.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AnimatePresence } from "framer-motion";
import React from "react";
import ReactDOM from "react-dom";
import shallow from "zustand/shallow";
Expand All @@ -15,18 +16,19 @@ const Toasts = () => {
if (typeof window === "undefined") return null;
const container = document.getElementById("overlays-root")!;

// TODO: timeouts to auto-remove, and transitions.
return ReactDOM.createPortal(
<div className="fixed w-screen h-screen top-0 left-0 p-3 flex items-end justify-end pointer-events-none">
<div
role="log"
className="w-full items-end flex flex-col gap-4 pointer-events-auto"
className="items-end flex flex-col gap-4 pointer-events-auto sm:max-w-sm w-full overflow-visible"
>
{toasts.map(({ id, className, children }) => (
<Toast key={id} className={className} onClose={() => popToast(id)}>
{children}
</Toast>
))}
<AnimatePresence initial={false}>
{toasts.map(({ id, children, ...props }) => (
<Toast key={id} onClose={() => popToast(id)} {...props}>
{children}
</Toast>
))}
</AnimatePresence>
</div>
</div>,
container
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"avoca": "^1.3.4",
"classcat": "^5.0.3",
"cookie": "^0.4.1",
"framer-motion": "^4.1.17",
"jose": "^3.12.3",
"murmurhash": "^2.0.0",
"next": "^10.2.3",
Expand Down
60 changes: 60 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@
"@babel/helper-validator-identifier" "^7.14.0"
to-fast-properties "^2.0.0"

"@emotion/is-prop-valid@^0.8.2":
version "0.8.8"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
dependencies:
"@emotion/memoize" "0.7.4"

"@emotion/[email protected]":
version "0.7.4"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==

"@eslint/eslintrc@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14"
Expand Down Expand Up @@ -1496,6 +1508,26 @@ fraction.js@^4.1.1:
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff"
integrity sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==

framer-motion@^4.1.17:
version "4.1.17"
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.17.tgz#4029469252a62ea599902e5a92b537120cc89721"
integrity sha512-thx1wvKzblzbs0XaK2X0G1JuwIdARcoNOW7VVwjO8BUltzXPyONGAElLu6CiCScsOQRI7FIk/45YTFtJw5Yozw==
dependencies:
framesync "5.3.0"
hey-listen "^1.0.8"
popmotion "9.3.6"
style-value-types "4.1.4"
tslib "^2.1.0"
optionalDependencies:
"@emotion/is-prop-valid" "^0.8.2"

[email protected]:
version "5.3.0"
resolved "https://registry.yarnpkg.com/framesync/-/framesync-5.3.0.tgz#0ecfc955e8f5a6ddc8fdb0cc024070947e1a0d9b"
integrity sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==
dependencies:
tslib "^2.1.0"

fs-extra@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
Expand Down Expand Up @@ -1661,6 +1693,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==

hey-listen@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==

hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
Expand Down Expand Up @@ -2612,6 +2649,16 @@ [email protected]:
dependencies:
ts-pnp "^1.1.6"

[email protected]:
version "9.3.6"
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.3.6.tgz#b5236fa28f242aff3871b9e23721f093133248d1"
integrity sha512-ZTbXiu6zIggXzIliMi8LGxXBF5ST+wkpXGEjeTUDUOCdSQ356hij/xjeUdv0F8zCQNeqB1+PR5/BB+gC+QLAPw==
dependencies:
framesync "5.3.0"
hey-listen "^1.0.8"
style-value-types "4.1.4"
tslib "^2.1.0"

postcss-functions@^3:
version "3.0.0"
resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e"
Expand Down Expand Up @@ -3276,6 +3323,14 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==

[email protected]:
version "4.1.4"
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-4.1.4.tgz#80f37cb4fb024d6394087403dfb275e8bb627e75"
integrity sha512-LCJL6tB+vPSUoxgUBt9juXIlNJHtBMy8jkXzUJSBzeHWdBu6lhzHqCvLVkXFGsFIlNa2ln1sQHya/gzaFmB2Lg==
dependencies:
hey-listen "^1.0.8"
tslib "^2.1.0"

[email protected]:
version "3.3.2"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.3.2.tgz#2474601a26670a6049fb4d3f94bd91695b3ce018"
Expand Down Expand Up @@ -3451,6 +3506,11 @@ tslib@^1.8.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==

tslib@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==

tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
Expand Down

0 comments on commit 0001954

Please sign in to comment.