{"version":3,"file":"index.cjs","sources":["../../../src/components/useToast/index.ts"],"sourcesContent":["// Inspired by react-hot-toast library\nimport * as React from 'react'\n\nimport type { ToastActionElement, ToastProps } from '@/components/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    dispatch({\n      type: 'REMOVE_TOAST',\n      toastId: 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) =>\n          t.id === action.toast.id ? { ...t, ...action.toast } : t,\n        ),\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  }\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: id,\n    dismiss,\n    update,\n  }\n}\n\nfunction useToast() {\n  const [state, setState] = React.useState<State>(memoryState)\n\n  React.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\n"],"names":["count","toastTimeouts","Map","addToRemoveQueue","toastId","has","timeout","setTimeout","delete","dispatch","type","set","reducer","state","action","toasts","toast","slice","map","t","id","forEach","open","filter","listeners","memoryState","listener","props","Number","MAX_SAFE_INTEGER","toString","dismiss","onOpenChange","update","setState","React","useState","useEffect","push","index","indexOf","splice"],"mappings":"uXAsBA,IAAIA,EAAQ,EA+BZ,MAAMC,MAAoBC,IAEpBC,EAAoBC,IACpB,GAAAH,EAAcI,IAAID,GACpB,OAGI,MAAAE,EAAUC,YAAW,KACzBN,EAAcO,OAAOJ,GACZK,EAAA,CACPC,KAAM,eACNN,WACD,GA3DsB,KA8DXH,EAAAU,IAAIP,EAASE,EAAO,EAGvBM,EAAU,CAACC,EAAcC,KACpC,OAAQA,EAAOJ,MACb,IAAK,YACI,MAAA,IACFG,EACHE,OAAQ,CAACD,EAAOE,SAAUH,EAAME,QAAQE,MAAM,EAvElC,IA0EhB,IAAK,eACI,MAAA,IACFJ,EACHE,OAAQF,EAAME,OAAOG,KAAKC,GACxBA,EAAEC,KAAON,EAAOE,MAAMI,GAAK,IAAKD,KAAML,EAAOE,OAAUG,KAI7D,IAAK,gBAAiB,CACd,MAAAf,QAAEA,GAAYU,EAYb,OARHV,EACFD,EAAiBC,GAEXS,EAAAE,OAAOM,SAASL,IACpBb,EAAiBa,EAAMI,GAAE,IAItB,IACFP,EACHE,OAAQF,EAAME,OAAOG,KAAKC,GACxBA,EAAEC,KAAOhB,QAAuB,IAAZA,EAChB,IACGe,EACHG,MAAM,GAENH,IAGV,CACA,IAAK,eACC,YAAmB,IAAnBL,EAAOV,QACF,IACFS,EACHE,OAAQ,IAGL,IACFF,EACHE,OAAQF,EAAME,OAAOQ,QAAQJ,GAAMA,EAAEC,KAAON,EAAOV,WAEzD,EAGIoB,EAA2C,GAEjD,IAAIC,EAAqB,CAAEV,OAAQ,IAEnC,SAASN,EAASK,GACFW,EAAAb,EAAQa,EAAaX,GACzBU,EAAAH,SAASK,IACjBA,EAASD,EAAW,GAExB,CAIA,SAAST,MAAWW,IAClB,MAAMP,GAnHGpB,GAAAA,EAAQ,GAAK4B,OAAOC,iBACtB7B,EAAM8B,YAyHPC,EAAU,IAAMtB,EAAS,CAAEC,KAAM,gBAAiBN,QAASgB,IAc1D,OAZEX,EAAA,CACPC,KAAM,YACNM,MAAO,IACFW,EACHP,KACAE,MAAM,EACNU,aAAeV,IACRA,WAKJ,CACLF,KACAW,UACAE,OAtBcN,GACdlB,EAAS,CACPC,KAAM,eACNM,MAAO,IAAKW,EAAOP,QAqBzB,oDAEA,WACE,MAAOP,EAAOqB,GAAYC,EAAMC,SAAgBX,GAYzC,OAVPU,EAAME,WAAU,KACdb,EAAUc,KAAKJ,GACR,KACC,MAAAK,EAAQf,EAAUgB,QAAQN,GAC5BK,GAAY,GACJf,EAAAiB,OAAOF,EAAO,EAC1B,IAED,CAAC1B,IAEG,IACFA,EACHG,QACAe,QAAU3B,GAAqBK,EAAS,CAAEC,KAAM,gBAAiBN,YAErE"}