{"version":3,"file":"ToasterHooks.cjs","names":[],"sources":["../src/hooks/use-toast.ts"],"sourcesContent":["import React, { useEffect } from 'react';\n\nimport type { ToastActionElement, ToastProps } from '@/components/ui/toast';\n\nconst TOAST_LIMIT = 1;\nconst TOAST_REMOVE_DELAY = 1000000;\n\ntype ToasterToast = ToastProps & {\n  id: string;\n  title?: React.ReactNode;\n  description?: React.ReactNode;\n  action?: ToastActionElement;\n};\n\nconst actionTypes = {\n  ADD_TOAST: 'ADD_TOAST',\n  UPDATE_TOAST: 'UPDATE_TOAST',\n  DISMISS_TOAST: 'DISMISS_TOAST',\n  REMOVE_TOAST: 'REMOVE_TOAST',\n} as const;\n\nlet count = 0;\n\nfunction genId() {\n  count = (count + 1) % Number.MAX_SAFE_INTEGER;\n  return count.toString();\n}\n\ntype ActionType = typeof actionTypes;\n\ntype Action =\n  | {\n      type: ActionType['ADD_TOAST'];\n      toast: ToasterToast;\n    }\n  | {\n      type: ActionType['UPDATE_TOAST'];\n      toast: Partial<ToasterToast>;\n    }\n  | {\n      type: ActionType['DISMISS_TOAST'];\n      toastId?: ToasterToast['id'];\n    }\n  | {\n      type: ActionType['REMOVE_TOAST'];\n      toastId?: ToasterToast['id'];\n    };\n\ninterface State {\n  toasts: ToasterToast[];\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();\n\nconst addToRemoveQueue = (toastId: string) => {\n  if (toastTimeouts.has(toastId)) {\n    return;\n  }\n\n  const timeout = setTimeout(() => {\n    toastTimeouts.delete(toastId);\n\n    dispatch({\n      type: 'REMOVE_TOAST',\n      toastId,\n    });\n  }, TOAST_REMOVE_DELAY);\n\n  toastTimeouts.set(toastId, timeout);\n};\n\nexport const reducer = (state: State, action: Action): State => {\n  switch (action.type) {\n    case 'ADD_TOAST':\n      return {\n        ...state,\n        toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n      };\n\n    case 'UPDATE_TOAST':\n      return {\n        ...state,\n        toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),\n      };\n\n    case 'DISMISS_TOAST': {\n      const { toastId } = action;\n\n      // ! Side effects ! - This could be extracted into a dismissToast() action,\n      // but I'll keep it here for simplicity\n      if (toastId) {\n        addToRemoveQueue(toastId);\n      } else {\n        state.toasts.forEach((toast) => {\n          addToRemoveQueue(toast.id);\n        });\n      }\n\n      return {\n        ...state,\n        toasts: state.toasts.map((t) =>\n          t.id === toastId || toastId === undefined\n            ? {\n                ...t,\n                open: false,\n              }\n            : t,\n        ),\n      };\n    }\n    case 'REMOVE_TOAST':\n      if (action.toastId === undefined) {\n        return {\n          ...state,\n          toasts: [],\n        };\n      }\n      return {\n        ...state,\n        toasts: state.toasts.filter((t) => t.id !== action.toastId),\n      };\n    default:\n      return { ...state };\n  }\n};\n\nconst listeners: Array<(state: State) => void> = [];\n\nlet memoryState: State = { toasts: [] };\n\nfunction dispatch(action: Action) {\n  memoryState = reducer(memoryState, action);\n  listeners.forEach((listener) => {\n    listener(memoryState);\n  });\n}\n\ntype Toast = Omit<ToasterToast, 'id'>;\n\nfunction toast({ ...props }: Toast) {\n  const id = genId();\n\n  const update = (props: ToasterToast) =>\n    dispatch({\n      type: 'UPDATE_TOAST',\n      toast: { ...props, id },\n    });\n  const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id });\n\n  dispatch({\n    type: 'ADD_TOAST',\n    toast: {\n      ...props,\n      id,\n      open: true,\n      onOpenChange: (open) => {\n        if (!open) dismiss();\n      },\n    },\n  });\n\n  return {\n    id,\n    dismiss,\n    update,\n  };\n}\n\nfunction useToast() {\n  const [state, setState] = React.useState<State>(memoryState);\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: this come from shad/cn\n  useEffect(() => {\n    listeners.push(setState);\n    return () => {\n      const index = listeners.indexOf(setState);\n      if (index > -1) {\n        listeners.splice(index, 1);\n      }\n    };\n  }, [state]);\n\n  return {\n    ...state,\n    toast,\n    dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),\n  };\n}\n\nexport { toast, useToast };\n"],"mappings":"wJAIA,IAAM,EAAc,EACd,EAAqB,IAgBvB,EAAQ,EAEZ,SAAS,GAAQ,CAEf,MADA,IAAS,EAAQ,aACV,EAAM,SAAS,CACxB,CA0BA,IAAM,EAAgB,IAAI,IAEpB,EAAoB,GAAoB,CAC5C,GAAI,EAAc,IAAI,CAAO,EAC3B,OAGF,IAAM,EAAU,eAAiB,CAC/B,EAAc,OAAO,CAAO,EAE5B,EAAS,CACP,KAAM,eACN,SACF,CAAC,CACH,EAAG,CAAkB,EAErB,EAAc,IAAI,EAAS,CAAO,CACpC,EAEa,GAAW,EAAc,IAA0B,CAC9D,OAAQ,EAAO,KAAf,CACE,IAAK,YACH,MAAO,CACL,GAAG,EACH,OAAQ,CAAC,EAAO,MAAO,GAAG,EAAM,MAAM,CAAC,CAAC,MAAM,EAAG,CAAW,CAC9D,EAEF,IAAK,eACH,MAAO,CACL,GAAG,EACH,OAAQ,EAAM,OAAO,IAAK,GAAO,EAAE,KAAO,EAAO,MAAM,GAAK,CAAE,GAAG,EAAG,GAAG,EAAO,KAAM,EAAI,CAAE,CAC5F,EAEF,IAAK,gBAAiB,CACpB,GAAM,CAAE,WAAY,EAYpB,OARI,EACF,EAAiB,CAAO,EAExB,EAAM,OAAO,QAAS,GAAU,CAC9B,EAAiB,EAAM,EAAE,CAC3B,CAAC,EAGI,CACL,GAAG,EACH,OAAQ,EAAM,OAAO,IAAK,GACxB,EAAE,KAAO,GAAW,IAAY,IAAA,GAC5B,CACE,GAAG,EACH,KAAM,EACR,EACA,CACN,CACF,CACF,CACA,IAAK,eAOH,OANI,EAAO,UAAY,IAAA,GACd,CACL,GAAG,EACH,OAAQ,CAAC,CACX,EAEK,CACL,GAAG,EACH,OAAQ,EAAM,OAAO,OAAQ,GAAM,EAAE,KAAO,EAAO,OAAO,CAC5D,EACF,QACE,MAAO,CAAE,GAAG,CAAM,CACtB,CACF,EAEM,EAA2C,CAAC,EAE9C,EAAqB,CAAE,OAAQ,CAAC,CAAE,EAEtC,SAAS,EAAS,EAAgB,CAChC,EAAc,EAAQ,EAAa,CAAM,EACzC,EAAU,QAAS,GAAa,CAC9B,EAAS,CAAW,CACtB,CAAC,CACH,CAIA,SAAS,EAAM,CAAE,GAAG,GAAgB,CAClC,IAAM,EAAK,EAAM,EAEX,EAAU,GACd,EAAS,CACP,KAAM,eACN,MAAO,CAAE,GAAG,EAAO,IAAG,CACxB,CAAC,EACG,MAAgB,EAAS,CAAE,KAAM,gBAAiB,QAAS,CAAG,CAAC,EAcrE,OAZA,EAAS,CACP,KAAM,YACN,MAAO,CACL,GAAG,EACH,KACA,KAAM,GACN,aAAe,GAAS,CACjB,GAAM,EAAQ,CACrB,CACF,CACF,CAAC,EAEM,CACL,KACA,UACA,QACF,CACF,CAEA,SAAS,GAAW,CAClB,GAAM,CAAC,EAAO,GAAY,EAAA,QAAM,SAAgB,CAAW,EAa3D,OAVA,EAAA,EAAA,UAAA,MACE,EAAU,KAAK,CAAQ,MACV,CACX,IAAM,EAAQ,EAAU,QAAQ,CAAQ,EACpC,EAAQ,IACV,EAAU,OAAO,EAAO,CAAC,CAE7B,GACC,CAAC,CAAK,CAAC,EAEH,CACL,GAAG,EACH,QACA,QAAU,GAAqB,EAAS,CAAE,KAAM,gBAAiB,SAAQ,CAAC,CAC5E,CACF"}