@@ -10,6 +10,7 @@ import type {
1010
1111const TOAST_LIMIT = 5
1212const TOAST_REMOVE_DELAY = 5000
13+ const TOAST_AUTO_DISMISS_DELAY = 2000
1314
1415type ToasterToast = ToastProps & {
1516 id : string
@@ -55,6 +56,17 @@ interface State {
5556}
5657
5758const toastTimeouts = new Map < string , ReturnType < typeof setTimeout > > ( )
59+ const toastAutoDismissTimeouts = new Map < string , ReturnType < typeof setTimeout > > ( )
60+
61+ const clearAutoDismissTimeout = ( toastId : string ) => {
62+ const timeout = toastAutoDismissTimeouts . get ( toastId )
63+ if ( ! timeout ) {
64+ return
65+ }
66+
67+ clearTimeout ( timeout )
68+ toastAutoDismissTimeouts . delete ( toastId )
69+ }
5870
5971const addToRemoveQueue = ( toastId : string ) => {
6072 if ( toastTimeouts . has ( toastId ) ) {
@@ -94,8 +106,11 @@ export const reducer = (state: State, action: Action): State => {
94106 // ! Side effects ! - This could be extracted into a dismissToast() action,
95107 // but I'll keep it here for simplicity
96108 if ( toastId ) {
109+ clearAutoDismissTimeout ( toastId )
97110 addToRemoveQueue ( toastId )
98111 } else {
112+ toastAutoDismissTimeouts . forEach ( ( timeout ) => clearTimeout ( timeout ) )
113+ toastAutoDismissTimeouts . clear ( )
99114 state . toasts . forEach ( ( toast ) => {
100115 addToRemoveQueue ( toast . id )
101116 } )
@@ -115,11 +130,14 @@ export const reducer = (state: State, action: Action): State => {
115130 }
116131 case "REMOVE_TOAST" :
117132 if ( action . toastId === undefined ) {
133+ toastAutoDismissTimeouts . forEach ( ( timeout ) => clearTimeout ( timeout ) )
134+ toastAutoDismissTimeouts . clear ( )
118135 return {
119136 ...state ,
120137 toasts : [ ] ,
121138 }
122139 }
140+ clearAutoDismissTimeout ( action . toastId )
123141 return {
124142 ...state ,
125143 toasts : state . toasts . filter ( ( t ) => t . id !== action . toastId ) ,
@@ -142,6 +160,8 @@ type Toast = Omit<ToasterToast, "id">
142160
143161function toast ( { ...props } : Toast ) {
144162 const id = genId ( )
163+ const autoDismissDuration =
164+ typeof props . duration === "number" ? props . duration : TOAST_AUTO_DISMISS_DELAY
145165
146166 const update = ( props : ToasterToast ) =>
147167 dispatch ( {
@@ -162,6 +182,15 @@ function toast({ ...props }: Toast) {
162182 } ,
163183 } )
164184
185+ if ( Number . isFinite ( autoDismissDuration ) && autoDismissDuration > 0 ) {
186+ const timeout = setTimeout ( ( ) => {
187+ toastAutoDismissTimeouts . delete ( id )
188+ dispatch ( { type : "DISMISS_TOAST" , toastId : id } )
189+ } , autoDismissDuration )
190+
191+ toastAutoDismissTimeouts . set ( id , timeout )
192+ }
193+
165194 return {
166195 id : id ,
167196 dismiss,
0 commit comments