UNPKG

braid-design-system

Version:
125 lines (124 loc) 3.79 kB
"use strict"; const jsxRuntime = require("react/jsx-runtime"); const react = require("react"); const lib_components_BraidPortal_BraidPortal_cjs = require("../BraidPortal/BraidPortal.cjs"); const lib_components_useToast_Toaster_cjs = require("./Toaster.cjs"); let toastCounter = 0; const ToastControllerContext = react.createContext(null); const QUEUE_TOAST = 0; const REMOVE_TOAST = 1; function reducer(state, action) { switch (action.type) { case QUEUE_TOAST: { const { toast } = action; const hasExistingToast = state.toasts.some( (t) => t.dedupeKey === toast.dedupeKey ); if (hasExistingToast) { return { toasts: state.toasts.map((t) => { if (t.dedupeKey === toast.dedupeKey) { return { ...t, shouldRemove: true }; } return t; }), queuedToasts: { ...state.queuedToasts, [toast.dedupeKey]: toast } }; } return { ...state, toasts: [...state.toasts, action.toast] }; } case REMOVE_TOAST: { const toasts = state.toasts.filter( ({ dedupeKey }) => dedupeKey !== action.dedupeKey ); const queuedToast = state.queuedToasts[action.dedupeKey]; if (queuedToast) { return { queuedToasts: { ...state.queuedToasts, [action.dedupeKey]: void 0 }, toasts: [...toasts, queuedToast] }; } return { ...state, toasts }; } } } const InternalToastProvider = ({ children }) => { const [{ toasts }, dispatch] = react.useReducer(reducer, { toasts: [], queuedToasts: {} }); const addToast = react.useCallback( (toast) => dispatch({ type: QUEUE_TOAST, toast }), [] ); const removeToast = react.useCallback( (dedupeKey) => dispatch({ type: REMOVE_TOAST, dedupeKey }), [] ); return /* @__PURE__ */ jsxRuntime.jsxs(ToastControllerContext.Provider, { value: addToast, children: [ children, /* @__PURE__ */ jsxRuntime.jsx(ToastPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(lib_components_useToast_Toaster_cjs.Toaster, { toasts, removeToast }) }) ] }); }; const ToastProvider = ({ children }) => { const currentContext = react.useContext(ToastControllerContext); if (currentContext !== null) { return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children }); } return /* @__PURE__ */ jsxRuntime.jsx(InternalToastProvider, { children }); }; const ToastPortal = ({ children }) => { const [toastElement, setElement] = react.useState(null); react.useEffect(() => { const toastContainerId = "braid-toast-container"; let element = document.getElementById(toastContainerId); if (!element) { element = document.createElement("div"); element.setAttribute("id", toastContainerId); element.setAttribute("class", ""); document.body.appendChild(element); } setElement(element); }, []); if (!toastElement) { return null; } return /* @__PURE__ */ jsxRuntime.jsx(lib_components_BraidPortal_BraidPortal_cjs.BraidPortal, { container: toastElement, children }); }; const useToast = () => { const addToast = react.useContext(ToastControllerContext); if (addToast === null) { throw new Error('No "ToastProvider" configured'); } return react.useCallback( (toast) => { const toastKey = `${toastCounter++}`; const { key, ...rest } = toast; const dedupeKey = key ?? toastKey; addToast({ ...rest, toastKey, dedupeKey, shouldRemove: false }); }, [addToast] ); }; exports.ToastProvider = ToastProvider; exports.useToast = useToast;