Skip to content

Commit ca5babc

Browse files
authored
fix(toast): enable proper exit animations (#5121)
* fix(toast): enable proper exit animations • Use LazyMotion and AnimatePresence in ToastProvider to support exit animations. • Simplify Toast by removing redundant LazyMotion wrapper. • Add motionProps to stories for easier animation customization. * chore(changeset): add changeset for ToastProvider exit animations * chore(toast): clean up stories by removing motionProps argument * chore(docs): revert `CONTRIBUTING.md` and `toast.stories.tsx`to initial state
1 parent 0cc127b commit ca5babc

File tree

3 files changed

+35
-31
lines changed

3 files changed

+35
-31
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@heroui/toast": patch
3+
---
4+
5+
- Use LazyMotion and AnimatePresence in ToastProvider to support exit animations.

packages/components/toast/src/toast-provider.tsx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import {ToastOptions, ToastQueue, useToastQueue} from "@react-stately/toast";
22
import {useProviderContext} from "@heroui/system";
3+
import {AnimatePresence, LazyMotion} from "framer-motion";
34

45
import {RegionProps, ToastRegion} from "./toast-region";
56
import {ToastProps, ToastPlacement} from "./use-toast";
67

8+
const loadFeatures = () => import("framer-motion").then((res) => res.domMax);
9+
710
let globalToastQueue: ToastQueue<ToastProps> | null = null;
811

912
interface ToastProviderProps {
@@ -37,20 +40,22 @@ export const ToastProvider = ({
3740
const globalContext = useProviderContext();
3841
const disableAnimation = disableAnimationProp ?? globalContext?.disableAnimation ?? false;
3942

40-
if (toastQueue.visibleToasts.length == 0) {
41-
return null;
42-
}
43-
4443
return (
45-
<ToastRegion
46-
disableAnimation={disableAnimation}
47-
maxVisibleToasts={maxVisibleToasts}
48-
placement={placement}
49-
toastOffset={toastOffset}
50-
toastProps={toastProps}
51-
toastQueue={toastQueue}
52-
{...regionProps}
53-
/>
44+
<LazyMotion features={loadFeatures}>
45+
<AnimatePresence>
46+
{toastQueue.visibleToasts.length > 0 ? (
47+
<ToastRegion
48+
disableAnimation={disableAnimation}
49+
maxVisibleToasts={maxVisibleToasts}
50+
placement={placement}
51+
toastOffset={toastOffset}
52+
toastProps={toastProps}
53+
toastQueue={toastQueue}
54+
{...regionProps}
55+
/>
56+
) : null}
57+
</AnimatePresence>
58+
</LazyMotion>
5459
);
5560
};
5661

packages/components/toast/src/toast.tsx

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ import {
77
SuccessIcon,
88
WarningIcon,
99
} from "@heroui/shared-icons";
10-
import {AnimatePresence, m, LazyMotion} from "framer-motion";
10+
import {m} from "framer-motion";
1111
import {cloneElement, isValidElement} from "react";
1212
import {Spinner} from "@heroui/spinner";
1313

1414
import {UseToastProps, useToast} from "./use-toast";
1515

16-
const loadFeatures = () => import("framer-motion").then((res) => res.domMax);
17-
1816
export interface ToastProps extends UseToastProps {}
1917

2018
const iconMap = {
@@ -108,21 +106,17 @@ const Toast = forwardRef<"div", ToastProps>((props, ref) => {
108106
{disableAnimation ? (
109107
toastContent
110108
) : (
111-
<LazyMotion features={loadFeatures}>
112-
<AnimatePresence>
113-
<m.div {...getMotionDivProps()}>
114-
<m.div
115-
key={"inner-div"}
116-
animate={{opacity: 1}}
117-
exit={{opacity: 0}}
118-
initial={{opacity: 0}}
119-
transition={{duration: 0.25, ease: "easeOut", delay: 0.1}}
120-
>
121-
{toastContent}
122-
</m.div>
123-
</m.div>
124-
</AnimatePresence>
125-
</LazyMotion>
109+
<m.div {...getMotionDivProps()}>
110+
<m.div
111+
key={"inner-div"}
112+
animate={{opacity: 1}}
113+
exit={{opacity: 0}}
114+
initial={{opacity: 0}}
115+
transition={{duration: 0.25, ease: "easeOut", delay: 0.1}}
116+
>
117+
{toastContent}
118+
</m.div>
119+
</m.div>
126120
)}
127121
</>
128122
);

0 commit comments

Comments
 (0)