UNPKG

@undp/design-system-react

Version:

React based design system for UNDP

1 lines 6.11 kB
{"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"}