toast-23 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ import { InternalToast, ToasterAction, ToasterContextValue } from './types';
2
+ export declare const ToasterContext: import('react').Context<ToasterContextValue | null>;
3
+ export declare function toasterReducer(state: InternalToast[], action: ToasterAction): InternalToast[];
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAMjB,eAAO,MAAM,cAAc,qDAAkD,CAAC;AAM9E,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EAAE,EACtB,MAAM,EAAE,aAAa,GACpB,aAAa,EAAE,CAqDjB"}
@@ -0,0 +1,16 @@
1
+ import { SVGProps, FC } from 'react';
2
+ type IconProps = SVGProps<SVGSVGElement>;
3
+ /** Green filled circle with white checkmark */
4
+ export declare const CheckCircleIcon: FC<IconProps>;
5
+ /** Red filled circle with white exclamation */
6
+ export declare const XCircleIcon: FC<IconProps>;
7
+ /** Yellow filled triangle with white exclamation */
8
+ export declare const AlertTriangleIcon: FC<IconProps>;
9
+ /** Blue filled circle with white "i" */
10
+ export declare const InfoIcon: FC<IconProps>;
11
+ /** Thin X icon for dismiss button */
12
+ export declare const XIcon: FC<IconProps>;
13
+ /** CSS-only loading spinner */
14
+ export declare const SpinnerIcon: FC<IconProps>;
15
+ export {};
16
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAE1C,KAAK,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;AAEzC,+CAA+C;AAC/C,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,SAAS,CAmBzC,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,SAAS,CAqBrC,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,SAAS,CAwB3C,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,SAAS,CAqBlC,CAAC;AAEF,qCAAqC;AACrC,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,SAAS,CAgB/B,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,SAAS,CAgBrC,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),l=require("react"),D=require("react-dom/client");function A(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const t=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,t.get?t:{enumerable:!0,get:()=>e[r]})}}return n.default=e,Object.freeze(n)}const y=A(l),k=l.createContext(null);function P(e,n){switch(n.type){case"ADD":return[...e,n.toast];case"UPSERT":return e.some(t=>t.id===n.toast.id)?e.map(t=>t.id===n.toast.id?{...t,...n.toast,version:t.version+1,isExiting:!1}:t):[...e,n.toast];case"UPDATE":return e.map(r=>r.id===n.id?{...r,...n.updates,version:r.version+1,isExiting:!1}:r);case"DISMISS":return n.id?e.map(r=>r.id===n.id?{...r,isExiting:!0}:r):e.map(r=>({...r,isExiting:!0}));case"REMOVE":return n.id?e.filter(r=>r.id!==n.id):[];default:return e}}const _=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("circle",{cx:12,cy:12,r:10,fill:"currentColor"}),o.jsx("path",{d:"M8 12.5l2.5 2.5 5-5",stroke:"#fff",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",fill:"none"})]}),p=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("circle",{cx:12,cy:12,r:10,fill:"currentColor"}),o.jsx("line",{x1:12,y1:8,x2:12,y2:13,stroke:"#fff",strokeWidth:2,strokeLinecap:"round"}),o.jsx("circle",{cx:12,cy:16,r:1,fill:"#fff"})]}),q=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("path",{d:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z",fill:"currentColor"}),o.jsx("line",{x1:12,y1:9.5,x2:12,y2:14,stroke:"#fff",strokeWidth:2,strokeLinecap:"round"}),o.jsx("circle",{cx:12,cy:17,r:1,fill:"#fff"})]}),b=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("circle",{cx:12,cy:12,r:10,fill:"currentColor"}),o.jsx("line",{x1:12,y1:11,x2:12,y2:16,stroke:"#fff",strokeWidth:2,strokeLinecap:"round"}),o.jsx("circle",{cx:12,cy:8,r:1,fill:"#fff"})]}),$=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"0.875em",height:"0.875em",...e,children:[o.jsx("line",{x1:18,y1:6,x2:6,y2:18}),o.jsx("line",{x1:6,y1:6,x2:18,y2:18})]}),B=e=>o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"1.25em",height:"1.25em",className:"toast23-spinner",...e,children:o.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})});let W=0;function U(){return`t23-${++W}-${Math.random().toString(36).slice(2,9)}`}function w(...e){return e.filter(Boolean).join(" ")}const F={success:_,error:p,warning:q,info:b,default:b,loading:B},X=300,z=200,M=y.memo(({toast:e,onDismiss:n,onRemove:r})=>{const[t,u]=l.useState(!1);l.useEffect(()=>{const v=requestAnimationFrame(()=>u(!0));return()=>cancelAnimationFrame(v)},[]),l.useEffect(()=>{if(!e.isExiting)return;const v=e.removeDelay??X,E=setTimeout(()=>r(e.id),v);return()=>clearTimeout(E)},[e.isExiting,e.id,e.removeDelay,r]);const[m,g]=l.useState(!1),d=l.useRef(e.duration),c=l.useRef(0),[x,f]=l.useState(100),[a,i]=l.useState("none"),s=l.useRef(0);l.useEffect(()=>{d.current=e.duration,f(100),i("none")},[e.version,e.duration]),l.useEffect(()=>{if(e.duration<=0||e.variant==="loading"||!t||e.isExiting)return;if(m){const I=Date.now()-c.current;d.current=Math.max(0,d.current-I);const L=Math.max(z,I);i(`width ${L}ms ease-out`),f(100);return}c.current=Date.now();const v=d.current;s.current=requestAnimationFrame(()=>{i(`width ${v}ms linear`),f(0)});const E=setTimeout(()=>{n(e.id)},v);return()=>{clearTimeout(E),cancelAnimationFrame(s.current)}},[m,t,e.isExiting,e.duration,e.variant,e.id,e.version,n]);const h=l.useCallback(()=>g(!0),[]),T=l.useCallback(()=>g(!1),[]),S=F[e.variant]??b;return e.isCustom?o.jsx("div",{className:w("toast23-item toast23-item--custom",!t&&"toast23-item--entering",e.isExiting&&"toast23-item--exiting"),role:"alert","aria-live":"polite","aria-atomic":"true",onMouseEnter:h,onMouseLeave:T,children:e.message}):o.jsxs("div",{className:w("toast23-item",`toast23-item--${e.variant}`,!t&&"toast23-item--entering",e.isExiting&&"toast23-item--exiting"),role:"alert","aria-live":e.variant==="error"?"assertive":"polite","aria-atomic":"true",onMouseEnter:h,onMouseLeave:T,children:[o.jsx("span",{className:w("toast23-icon",`toast23-icon--${e.variant}`),children:o.jsx(S,{})}),o.jsxs("div",{className:"toast23-content",children:[e.title&&o.jsx("div",{className:"toast23-title",children:e.title}),o.jsx("div",{className:w("toast23-message",e.title&&"toast23-message--with-title"),children:e.message})]}),e.dismissible&&o.jsx("button",{type:"button",className:"toast23-dismiss",onClick:()=>n(e.id),"aria-label":"Dismiss notification",children:o.jsx($,{})}),e.duration>0&&e.variant!=="loading"&&o.jsx("div",{className:w("toast23-progress",`toast23-progress--${e.variant}`),style:{width:`${x}%`,transition:a}})]})});M.displayName="ToastItem";const N=y.memo(({position:e,toasts:n,maxVisible:r})=>{const t=l.useContext(k);if(!t)return null;const u=n.filter(c=>!c.isExiting),m=n.filter(c=>c.isExiting),g=[...u.slice(0,r),...m];if(g.length===0)return null;const d=Math.max(0,u.length-r);return o.jsxs("div",{className:w("toast23-container",`toast23-container--${e}`),"aria-label":"Notifications",role:"region",children:[g.map(c=>o.jsx(M,{toast:c,onDismiss:t.dismissToast,onRemove:t.removeToast},c.id)),d>0&&o.jsxs("div",{className:"toast23-queue-badge","aria-live":"polite",children:["+",d," more"]})]})});N.displayName="ToastContainer";const H=["top-right","top-left","top-center","bottom-right","bottom-left","bottom-center"],C=({children:e,maxVisible:n=5,position:r="top-right",duration:t=5e3})=>{const[u,m]=l.useReducer(P,[]),g=l.useCallback((i,s)=>{const h=(s==null?void 0:s.id)??U(),T={id:h,message:i,title:s==null?void 0:s.title,variant:(s==null?void 0:s.variant)??"default",duration:(s==null?void 0:s.duration)??t,position:(s==null?void 0:s.position)??r,dismissible:(s==null?void 0:s.dismissible)??!0,removeDelay:(s==null?void 0:s.removeDelay)??1e3,isExiting:!1,createdAt:Date.now(),version:0,isCustom:s==null?void 0:s.isCustom};return s!=null&&s.id?m({type:"UPSERT",toast:T}):m({type:"ADD",toast:T}),h},[t,r]),d=l.useCallback((i,s)=>{m({type:"UPDATE",id:i,updates:s})},[]),c=l.useCallback(i=>{m({type:"DISMISS",id:i})},[]),x=l.useCallback(i=>{m({type:"REMOVE",id:i})},[]),f=l.useMemo(()=>({addToast:g,updateToast:d,dismissToast:c,removeToast:x,config:{maxVisible:n,position:r,duration:t}}),[g,d,c,x,n,r,t]),a=l.useMemo(()=>{const i={"top-right":[],"top-left":[],"top-center":[],"bottom-right":[],"bottom-left":[],"bottom-center":[]};for(const s of u)i[s.position].push(s);return i},[u]);return o.jsxs(k.Provider,{value:f,children:[e,H.map(i=>a[i].length>0?o.jsx(N,{position:i,toasts:a[i],maxVisible:n},i):null)]})};C.displayName="Toast23Provider";function R(){const e=l.useContext(k);if(!e)throw new Error("[toast-23] useToast() must be used inside a <Toast23Provider>. Wrap your application root with <Toast23Provider> to fix this.");return l.useMemo(()=>{const n=(r,t)=>e.addToast(r,t);return n.success=(r,t)=>e.addToast(r,{...t,variant:"success"}),n.error=(r,t)=>e.addToast(r,{...t,variant:"error"}),n.warning=(r,t)=>e.addToast(r,{...t,variant:"warning"}),n.info=(r,t)=>e.addToast(r,{...t,variant:"info"}),n.loading=(r,t)=>e.addToast(r,{...t,variant:"loading",duration:(t==null?void 0:t.duration)??0,dismissible:(t==null?void 0:t.dismissible)??!1}),n.custom=(r,t)=>e.addToast(r,{...t,variant:"default",isCustom:!0}),n.dismiss=r=>e.dismissToast(r),n.remove=r=>e.removeToast(r),n.promise=async(r,t,u)=>{const m=e.addToast(t.loading,{...u,variant:"loading",duration:0,dismissible:!1}),g=typeof r=="function"?r():r;try{const d=await g,c=typeof t.success=="function"?t.success(d):t.success;return e.updateToast(m,{message:c,variant:"success",duration:(u==null?void 0:u.duration)??e.config.duration,dismissible:!0}),d}catch(d){const c=typeof t.error=="function"?t.error(d):t.error;throw e.updateToast(m,{message:c,variant:"error",duration:(u==null?void 0:u.duration)??e.config.duration,dismissible:!0}),d}},n},[e.addToast,e.updateToast,e.dismissToast,e.removeToast,e.config.duration])}let j=null;function V(){const e=R();return y.useEffect(()=>{j&&(j(e),j=null)},[e]),null}function G(e={}){const{position:n="top-right",maxVisible:r=5,duration:t=5e3}=e,u=document.createElement("div");u.setAttribute("data-toast23-standalone",""),u.style.display="contents",document.body.appendChild(u);let m=D.createRoot(u);const g=new Promise(a=>{j=a}),d=[];let c=null;g.then(a=>{c=a;for(const i of d)i.method==="__call__"?a(...i.args):a[i.method](...i.args);d.length=0}),m.render(y.createElement(C,{position:n,maxVisible:r,duration:t},y.createElement(V)));const x=(a,...i)=>c?c[a](...i):(d.push({method:a,args:i}),"queued"),f=(a,i)=>c?c(a,i):(d.push({method:"__call__",args:[a,i]}),"queued");return f.success=(a,i)=>x("success",a,i),f.error=(a,i)=>x("error",a,i),f.warning=(a,i)=>x("warning",a,i),f.info=(a,i)=>x("info",a,i),f.loading=(a,i)=>x("loading",a,i),f.custom=(a,i)=>x("custom",a,i),f.dismiss=a=>x("dismiss",a),f.remove=a=>x("remove",a),f.promise=(a,i,s)=>c?c.promise(a,i,s):g.then(h=>h.promise(a,i,s)),f.destroy=()=>{m&&(m.unmount(),m=null),u.remove(),c=null},f}exports.Toast23Provider=C;exports.createToast23=G;exports.useToast=R;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),c=require("react"),M=require("react-dom/client");function S(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,i.get?i:{enumerable:!0,get:()=>e[t]})}}return r.default=e,Object.freeze(r)}const w=S(c),j=c.createContext(null);function N(e,r){switch(r.type){case"ADD":return[...e,r.toast];case"UPSERT":return e.some(i=>i.id===r.toast.id)?e.map(i=>i.id===r.toast.id?{...i,...r.toast,version:i.version+1,isExiting:!1}:i):[...e,r.toast];case"UPDATE":return e.map(t=>t.id===r.id?{...t,...r.updates,version:t.version+1,isExiting:!1}:t);case"DISMISS":return r.id?e.map(t=>t.id===r.id?{...t,isExiting:!0}:t):e.map(t=>({...t,isExiting:!0}));case"REMOVE":return r.id?e.filter(t=>t.id!==r.id):[];default:return e}}const L=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("circle",{cx:12,cy:12,r:10,fill:"currentColor"}),o.jsx("path",{d:"M8 12.5l2.5 2.5 5-5",stroke:"#fff",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",fill:"none"})]}),P=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("circle",{cx:12,cy:12,r:10,fill:"currentColor"}),o.jsx("line",{x1:12,y1:8,x2:12,y2:13,stroke:"#fff",strokeWidth:2,strokeLinecap:"round"}),o.jsx("circle",{cx:12,cy:16,r:1,fill:"#fff"})]}),A=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("path",{d:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z",fill:"currentColor"}),o.jsx("line",{x1:12,y1:9.5,x2:12,y2:14,stroke:"#fff",strokeWidth:2,strokeLinecap:"round"}),o.jsx("circle",{cx:12,cy:17,r:1,fill:"#fff"})]}),y=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1.25em",height:"1.25em",fill:"none",...e,children:[o.jsx("circle",{cx:12,cy:12,r:10,fill:"currentColor"}),o.jsx("line",{x1:12,y1:11,x2:12,y2:16,stroke:"#fff",strokeWidth:2,strokeLinecap:"round"}),o.jsx("circle",{cx:12,cy:8,r:1,fill:"#fff"})]}),R=e=>o.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"0.875em",height:"0.875em",...e,children:[o.jsx("line",{x1:18,y1:6,x2:6,y2:18}),o.jsx("line",{x1:6,y1:6,x2:18,y2:18})]}),_=e=>o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"1.25em",height:"1.25em",className:"toast23-spinner",...e,children:o.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})});let D=0;function q(){return`t23-${++D}-${Math.random().toString(36).slice(2,9)}`}function p(...e){return e.filter(Boolean).join(" ")}const B={success:L,error:P,warning:A,info:y,default:y,loading:_},$=300,b=w.memo(({toast:e,onDismiss:r,onRemove:t})=>{const[i,m]=c.useState(!1);c.useEffect(()=>{const h=requestAnimationFrame(()=>m(!0));return()=>cancelAnimationFrame(h)},[]),c.useEffect(()=>{if(!e.isExiting)return;const h=e.removeDelay??$,I=setTimeout(()=>t(e.id),h);return()=>clearTimeout(I)},[e.isExiting,e.id,e.removeDelay,t]);const[u,x]=c.useState(!1),d=c.useRef(e.duration),[a,f]=c.useState(100),[g,n]=c.useState("none");c.useEffect(()=>{d.current=e.duration,f(100),n("none")},[e.version,e.duration]),c.useEffect(()=>{if(e.duration<=0||e.variant==="loading"||!i||e.isExiting)return;if(u){n("width 200ms ease-out"),f(100);return}f(100),requestAnimationFrame(()=>{n(`width ${e.duration}ms linear`),f(0)});const h=setTimeout(()=>{r(e.id)},e.duration);return()=>clearTimeout(h)},[u,e.duration,e.variant,e.isExiting,e.id,i,r]);const s=c.useCallback(()=>x(!0),[]),l=c.useCallback(()=>x(!1),[]),v=B[e.variant]??y;return e.isCustom?o.jsx("div",{className:p("toast23-item toast23-item--custom",!i&&"toast23-item--entering",e.isExiting&&"toast23-item--exiting"),role:"alert","aria-live":"polite","aria-atomic":"true",onMouseEnter:s,onMouseLeave:l,children:e.message}):o.jsxs("div",{className:p("toast23-item",`toast23-item--${e.variant}`,!i&&"toast23-item--entering",e.isExiting&&"toast23-item--exiting"),role:"alert","aria-live":e.variant==="error"?"assertive":"polite","aria-atomic":"true",onMouseEnter:s,onMouseLeave:l,children:[o.jsx("span",{className:p("toast23-icon",`toast23-icon--${e.variant}`),children:o.jsx(v,{})}),o.jsxs("div",{className:"toast23-content",children:[e.title&&o.jsx("div",{className:"toast23-title",children:e.title}),o.jsx("div",{className:p("toast23-message",e.title&&"toast23-message--with-title"),children:e.message})]}),e.dismissible&&o.jsx("button",{type:"button",className:"toast23-dismiss",onClick:()=>r(e.id),"aria-label":"Dismiss notification",children:o.jsx(R,{})}),e.duration>0&&e.variant!=="loading"&&o.jsx("div",{className:p("toast23-progress",`toast23-progress--${e.variant}`),style:{width:`${a}%`,transition:g}})]})});b.displayName="ToastItem";const k=w.memo(({position:e,toasts:r,maxVisible:t})=>{const i=c.useContext(j);if(!i)return null;const m=r.filter(a=>!a.isExiting),u=r.filter(a=>a.isExiting),x=[...m.slice(0,t),...u];if(x.length===0)return null;const d=Math.max(0,m.length-t);return o.jsxs("div",{className:p("toast23-container",`toast23-container--${e}`),"aria-label":"Notifications",role:"region",children:[x.map(a=>o.jsx(b,{toast:a,onDismiss:i.dismissToast,onRemove:i.removeToast},a.id)),d>0&&o.jsxs("div",{className:"toast23-queue-badge","aria-live":"polite",children:["+",d," more"]})]})});k.displayName="ToastContainer";const W=["top-right","top-left","top-center","bottom-right","bottom-left","bottom-center"],E=({children:e,maxVisible:r=5,position:t="top-right",duration:i=5e3})=>{const[m,u]=c.useReducer(N,[]),x=c.useCallback((s,l)=>{const v=l?.id??q(),h={id:v,message:s,title:l?.title,variant:l?.variant??"default",duration:l?.duration??i,position:l?.position??t,dismissible:l?.dismissible??!0,removeDelay:l?.removeDelay??1e3,isExiting:!1,createdAt:Date.now(),version:0,isCustom:l?.isCustom};return l?.id?u({type:"UPSERT",toast:h}):u({type:"ADD",toast:h}),v},[i,t]),d=c.useCallback((s,l)=>{u({type:"UPDATE",id:s,updates:l})},[]),a=c.useCallback(s=>{u({type:"DISMISS",id:s})},[]),f=c.useCallback(s=>{u({type:"REMOVE",id:s})},[]),g=c.useMemo(()=>({addToast:x,updateToast:d,dismissToast:a,removeToast:f,config:{maxVisible:r,position:t,duration:i}}),[x,d,a,f,r,t,i]),n=c.useMemo(()=>{const s={"top-right":[],"top-left":[],"top-center":[],"bottom-right":[],"bottom-left":[],"bottom-center":[]};for(const l of m)s[l.position].push(l);return s},[m]);return o.jsxs(j.Provider,{value:g,children:[e,W.map(s=>n[s].length>0?o.jsx(k,{position:s,toasts:n[s],maxVisible:r},s):null)]})};E.displayName="Toast23Provider";function C(){const e=c.useContext(j);if(!e)throw new Error("[toast-23] useToast() must be used inside a <Toast23Provider>. Wrap your application root with <Toast23Provider> to fix this.");return c.useMemo(()=>{const r=((t,i)=>e.addToast(t,i));return r.success=(t,i)=>e.addToast(t,{...i,variant:"success"}),r.error=(t,i)=>e.addToast(t,{...i,variant:"error"}),r.warning=(t,i)=>e.addToast(t,{...i,variant:"warning"}),r.info=(t,i)=>e.addToast(t,{...i,variant:"info"}),r.loading=(t,i)=>e.addToast(t,{...i,variant:"loading",duration:i?.duration??0,dismissible:i?.dismissible??!1}),r.custom=(t,i)=>e.addToast(t,{...i,variant:"default",isCustom:!0}),r.dismiss=t=>e.dismissToast(t),r.remove=t=>e.removeToast(t),r.promise=async(t,i,m)=>{const u=e.addToast(i.loading,{...m,variant:"loading",duration:0,dismissible:!1}),x=typeof t=="function"?t():t;try{const d=await x,a=typeof i.success=="function"?i.success(d):i.success;return e.updateToast(u,{message:a,variant:"success",duration:m?.duration??e.config.duration,dismissible:!0}),d}catch(d){const a=typeof i.error=="function"?i.error(d):i.error;throw e.updateToast(u,{message:a,variant:"error",duration:m?.duration??e.config.duration,dismissible:!0}),d}},r},[e.addToast,e.updateToast,e.dismissToast,e.removeToast,e.config.duration])}let T=null;function O(){const e=C();return w.useEffect(()=>{T&&(T(e),T=null)},[e]),null}function U(e={}){const{position:r="top-right",maxVisible:t=5,duration:i=5e3}=e,m=document.createElement("div");m.setAttribute("data-toast23-standalone",""),m.style.display="contents",document.body.appendChild(m);let u=M.createRoot(m);const x=new Promise(n=>{T=n}),d=[];let a=null;x.then(n=>{a=n;for(const s of d)s.method==="__call__"?n(...s.args):n[s.method](...s.args);d.length=0}),u.render(w.createElement(E,{position:r,maxVisible:t,duration:i},w.createElement(O)));const f=(n,...s)=>a?a[n](...s):(d.push({method:n,args:s}),"queued"),g=((n,s)=>a?a(n,s):(d.push({method:"__call__",args:[n,s]}),"queued"));return g.success=(n,s)=>f("success",n,s),g.error=(n,s)=>f("error",n,s),g.warning=(n,s)=>f("warning",n,s),g.info=(n,s)=>f("info",n,s),g.loading=(n,s)=>f("loading",n,s),g.custom=(n,s)=>f("custom",n,s),g.dismiss=n=>f("dismiss",n),g.remove=n=>f("remove",n),g.promise=(n,s,l)=>a?a.promise(n,s,l):x.then(v=>v.promise(n,s,l)),g.destroy=()=>{u&&(u.unmount(),u=null),m.remove(),a=null},g}exports.Toast23Provider=E;exports.createToast23=U;exports.useToast=C;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/context.tsx","../src/icons.tsx","../src/utils.ts","../src/toast-item.tsx","../src/toast-container.tsx","../src/provider.tsx","../src/use-toast.ts","../src/standalone.ts"],"sourcesContent":["/**\r\n * toast-23 — React Context & Reducer\r\n */\r\n\r\nimport { createContext } from \"react\";\r\nimport type {\r\n InternalToast,\r\n ToasterAction,\r\n ToasterContextValue,\r\n} from \"./types\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Context — consumed by useToast() and internal components\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const ToasterContext = createContext<ToasterContextValue | null>(null);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Reducer — pure state transitions for the toast queue\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function toasterReducer(\r\n state: InternalToast[],\r\n action: ToasterAction,\r\n): InternalToast[] {\r\n switch (action.type) {\r\n case \"ADD\":\r\n return [...state, action.toast];\r\n\r\n case \"UPSERT\": {\r\n const exists = state.some((t) => t.id === action.toast.id);\r\n if (exists) {\r\n return state.map((t) =>\r\n t.id === action.toast.id\r\n ? {\r\n ...t,\r\n ...action.toast,\r\n version: t.version + 1,\r\n isExiting: false,\r\n }\r\n : t,\r\n );\r\n }\r\n return [...state, action.toast];\r\n }\r\n\r\n case \"UPDATE\":\r\n return state.map((t) =>\r\n t.id === action.id\r\n ? {\r\n ...t,\r\n ...action.updates,\r\n // Bump version so progress bar restarts\r\n version: t.version + 1,\r\n // If the toast was exiting, cancel exit on update\r\n isExiting: false,\r\n }\r\n : t,\r\n );\r\n\r\n case \"DISMISS\":\r\n // Omit id → dismiss all\r\n if (!action.id) {\r\n return state.map((t) => ({ ...t, isExiting: true }));\r\n }\r\n return state.map((t) =>\r\n t.id === action.id ? { ...t, isExiting: true } : t,\r\n );\r\n\r\n case \"REMOVE\":\r\n // Omit id → remove all instantly\r\n if (!action.id) return [];\r\n return state.filter((t) => t.id !== action.id);\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","/**\r\n * toast-23 — Inline SVG Icons (Filled style)\r\n *\r\n * Solid colored circles/triangles with white inner symbols,\r\n * matching the visual design reference.\r\n */\r\n\r\nimport type { SVGProps, FC } from \"react\";\r\n\r\ntype IconProps = SVGProps<SVGSVGElement>;\r\n\r\n/** Green filled circle with white checkmark */\r\nexport const CheckCircleIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <circle cx={12} cy={12} r={10} fill=\"currentColor\" />\r\n <path\r\n d=\"M8 12.5l2.5 2.5 5-5\"\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n fill=\"none\"\r\n />\r\n </svg>\r\n);\r\n\r\n/** Red filled circle with white exclamation */\r\nexport const XCircleIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <circle cx={12} cy={12} r={10} fill=\"currentColor\" />\r\n <line\r\n x1={12}\r\n y1={8}\r\n x2={12}\r\n y2={13}\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n <circle cx={12} cy={16} r={1} fill=\"#fff\" />\r\n </svg>\r\n);\r\n\r\n/** Yellow filled triangle with white exclamation */\r\nexport const AlertTriangleIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <path\r\n d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"\r\n fill=\"currentColor\"\r\n />\r\n <line\r\n x1={12}\r\n y1={9.5}\r\n x2={12}\r\n y2={14}\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n <circle cx={12} cy={17} r={1} fill=\"#fff\" />\r\n </svg>\r\n);\r\n\r\n/** Blue filled circle with white \"i\" */\r\nexport const InfoIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <circle cx={12} cy={12} r={10} fill=\"currentColor\" />\r\n <line\r\n x1={12}\r\n y1={11}\r\n x2={12}\r\n y2={16}\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n <circle cx={12} cy={8} r={1} fill=\"#fff\" />\r\n </svg>\r\n);\r\n\r\n/** Thin X icon for dismiss button */\r\nexport const XIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n width=\"0.875em\"\r\n height=\"0.875em\"\r\n {...props}\r\n >\r\n <line x1={18} y1={6} x2={6} y2={18} />\r\n <line x1={6} y1={6} x2={18} y2={18} />\r\n </svg>\r\n);\r\n\r\n/** CSS-only loading spinner */\r\nexport const SpinnerIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n className=\"toast23-spinner\"\r\n {...props}\r\n >\r\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\r\n </svg>\r\n);\r\n","/**\r\n * toast-23 — Utility helpers\r\n */\r\n\r\nlet counter = 0;\r\n\r\n/**\r\n * Generate a unique toast id.\r\n * Works in SSR (no dependency on `crypto`).\r\n */\r\nexport function generateId(): string {\r\n return `t23-${++counter}-${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Deterministic class-name builder (replaces clsx dependency).\r\n */\r\nexport function cx(...args: (string | false | null | undefined | 0)[]): string {\r\n return args.filter(Boolean).join(\" \");\r\n}\r\n","/**\r\n * toast-23 — Individual Toast Component\r\n *\r\n * Manages its own enter / exit CSS transitions and auto-dismiss timer.\r\n * Progress bar is JS-driven so it can reverse (refill) on hover.\r\n */\r\n\r\n\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { InternalToast } from \"./types\";\r\nimport {\r\n CheckCircleIcon,\r\n XCircleIcon,\r\n AlertTriangleIcon,\r\n InfoIcon,\r\n SpinnerIcon,\r\n XIcon,\r\n} from \"./icons\";\r\nimport { cx } from \"./utils\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Icon map\r\n// ---------------------------------------------------------------------------\r\n\r\nconst variantIcon: Record<string, React.FC<React.SVGProps<SVGSVGElement>>> = {\r\n success: CheckCircleIcon,\r\n error: XCircleIcon,\r\n warning: AlertTriangleIcon,\r\n info: InfoIcon,\r\n default: InfoIcon,\r\n loading: SpinnerIcon,\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Component\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ToastItemProps {\r\n toast: InternalToast;\r\n onDismiss: (id: string) => void;\r\n onRemove: (id: string) => void;\r\n}\r\n\r\nconst EXIT_DURATION = 300; // ms — must match CSS transition duration\r\nconst MIN_REFILL_DURATION = 200; // ms — minimum refill time so very short hovers aren't instant\r\n\r\nexport const ToastItem: React.FC<ToastItemProps> = React.memo(\r\n ({ toast, onDismiss, onRemove }) => {\r\n // ----- animation state -----\r\n const [hasEntered, setHasEntered] = useState(false);\r\n\r\n // Trigger enter transition on next frame\r\n useEffect(() => {\r\n const raf = requestAnimationFrame(() => setHasEntered(true));\r\n return () => cancelAnimationFrame(raf);\r\n }, []);\r\n\r\n // When the provider marks the toast as exiting, wait for the CSS\r\n // transition to finish then actually remove it from state.\r\n useEffect(() => {\r\n if (!toast.isExiting) return;\r\n const delay = toast.removeDelay ?? EXIT_DURATION;\r\n const timer = setTimeout(() => onRemove(toast.id), delay);\r\n return () => clearTimeout(timer);\r\n }, [toast.isExiting, toast.id, toast.removeDelay, onRemove]);\r\n\r\n // ----- auto-dismiss timer with hover-pause -----\r\n const [isPaused, setIsPaused] = useState(false);\r\n const remainingRef = useRef(toast.duration);\r\n const startRef = useRef(0);\r\n\r\n // ----- JS-driven progress bar -----\r\n // progress: 100 = full, 0 = empty\r\n const [progress, setProgress] = useState(100);\r\n // transition duration for the progress bar\r\n const [progressTransition, setProgressTransition] = useState(\"none\");\r\n const rafRef = useRef<number>(0);\r\n\r\n // Reset remaining time when version changes (e.g. promise resolved)\r\n useEffect(() => {\r\n remainingRef.current = toast.duration;\r\n setProgress(100);\r\n setProgressTransition(\"none\");\r\n }, [toast.version, toast.duration]);\r\n\r\n useEffect(() => {\r\n // Don't auto-dismiss: persistent, loading, still entering, or already exiting\r\n if (\r\n toast.duration <= 0 ||\r\n toast.variant === \"loading\" ||\r\n !hasEntered ||\r\n toast.isExiting\r\n )\r\n return;\r\n\r\n if (isPaused) {\r\n // How long the bar was shrinking before hover\r\n const elapsed = Date.now() - startRef.current;\r\n // Snapshot remaining time\r\n remainingRef.current = Math.max(0, remainingRef.current - elapsed);\r\n\r\n // Reverse at the same speed it was shrinking (proportional duration)\r\n const refillDuration = Math.max(MIN_REFILL_DURATION, elapsed);\r\n setProgressTransition(`width ${refillDuration}ms ease-out`);\r\n setProgress(100);\r\n return;\r\n }\r\n\r\n // Start shrinking\r\n startRef.current = Date.now();\r\n const remaining = remainingRef.current;\r\n\r\n // Set transition to match remaining time and shrink to 0\r\n // Use rAF to ensure the refill transition has settled before starting shrink\r\n rafRef.current = requestAnimationFrame(() => {\r\n setProgressTransition(`width ${remaining}ms linear`);\r\n setProgress(0);\r\n });\r\n\r\n const timer = setTimeout(() => {\r\n onDismiss(toast.id);\r\n }, remaining);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n cancelAnimationFrame(rafRef.current);\r\n };\r\n }, [\r\n isPaused,\r\n hasEntered,\r\n toast.isExiting,\r\n toast.duration,\r\n toast.variant,\r\n toast.id,\r\n toast.version,\r\n onDismiss,\r\n ]);\r\n\r\n // ----- handlers -----\r\n const handleMouseEnter = useCallback(() => setIsPaused(true), []);\r\n const handleMouseLeave = useCallback(() => setIsPaused(false), []);\r\n\r\n // ----- render -----\r\n const Icon = variantIcon[toast.variant] ?? InfoIcon;\r\n\r\n // Custom toast — render raw content with no default chrome\r\n if (toast.isCustom) {\r\n return (\r\n <div\r\n className={cx(\r\n \"toast23-item toast23-item--custom\",\r\n !hasEntered && \"toast23-item--entering\",\r\n toast.isExiting && \"toast23-item--exiting\",\r\n )}\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"true\"\r\n onMouseEnter={handleMouseEnter}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n {toast.message}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n \"toast23-item\",\r\n `toast23-item--${toast.variant}`,\r\n !hasEntered && \"toast23-item--entering\",\r\n toast.isExiting && \"toast23-item--exiting\",\r\n )}\r\n role=\"alert\"\r\n aria-live={toast.variant === \"error\" ? \"assertive\" : \"polite\"}\r\n aria-atomic=\"true\"\r\n onMouseEnter={handleMouseEnter}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n {/* Icon */}\r\n <span className={cx(\"toast23-icon\", `toast23-icon--${toast.variant}`)}>\r\n <Icon />\r\n </span>\r\n\r\n {/* Content */}\r\n <div className=\"toast23-content\">\r\n {toast.title && <div className=\"toast23-title\">{toast.title}</div>}\r\n <div\r\n className={cx(\r\n \"toast23-message\",\r\n toast.title && \"toast23-message--with-title\",\r\n )}\r\n >\r\n {toast.message}\r\n </div>\r\n </div>\r\n\r\n {/* Dismiss button */}\r\n {toast.dismissible && (\r\n <button\r\n type=\"button\"\r\n className=\"toast23-dismiss\"\r\n onClick={() => onDismiss(toast.id)}\r\n aria-label=\"Dismiss notification\"\r\n >\r\n <XIcon />\r\n </button>\r\n )}\r\n\r\n {/* Progress bar — JS-driven width for hover reversal */}\r\n {toast.duration > 0 && toast.variant !== \"loading\" && (\r\n <div\r\n className={cx(\r\n \"toast23-progress\",\r\n `toast23-progress--${toast.variant}`,\r\n )}\r\n style={{\r\n width: `${progress}%`,\r\n transition: progressTransition,\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nToastItem.displayName = \"ToastItem\";\r\n","/**\r\n * toast-23 — Positioned Toast Container\r\n *\r\n * Renders a group of toasts for a given screen position.\r\n * Handles queue logic: only `maxVisible` non-exiting toasts are shown,\r\n * plus any currently animating-out toasts.\r\n */\r\n\r\n\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { useContext } from \"react\";\r\nimport type { InternalToast, ToastPosition } from \"./types\";\r\nimport { ToasterContext } from \"./context\";\r\nimport { ToastItem } from \"./toast-item\";\r\nimport { cx } from \"./utils\";\r\n\r\ninterface ToastContainerProps {\r\n position: ToastPosition;\r\n toasts: InternalToast[];\r\n maxVisible: number;\r\n}\r\n\r\nexport const ToastContainer: React.FC<ToastContainerProps> = React.memo(\r\n ({ position, toasts, maxVisible }: ToastContainerProps) => {\r\n const ctx = useContext(ToasterContext);\r\n if (!ctx) return null;\r\n\r\n // Separate active vs. exiting toasts\r\n const active = toasts.filter((t) => !t.isExiting);\r\n const exiting = toasts.filter((t) => t.isExiting);\r\n\r\n // Only show up to maxVisible active toasts, plus all currently exiting\r\n const visible = [...active.slice(0, maxVisible), ...exiting];\r\n\r\n if (visible.length === 0) return null;\r\n\r\n // Queue count for optional badge\r\n const queuedCount = Math.max(0, active.length - maxVisible);\r\n\r\n return (\r\n <div\r\n className={cx(\"toast23-container\", `toast23-container--${position}`)}\r\n aria-label=\"Notifications\"\r\n role=\"region\"\r\n >\r\n {visible.map((toast) => (\r\n <ToastItem\r\n key={toast.id}\r\n toast={toast}\r\n onDismiss={ctx.dismissToast}\r\n onRemove={ctx.removeToast}\r\n />\r\n ))}\r\n {queuedCount > 0 && (\r\n <div className=\"toast23-queue-badge\" aria-live=\"polite\">\r\n +{queuedCount} more\r\n </div>\r\n )}\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nToastContainer.displayName = \"ToastContainer\";\r\n","/**\r\n * toast-23 — Toast23Provider\r\n *\r\n * Wrap your application with this provider to enable toast notifications.\r\n *\r\n * ```tsx\r\n * <Toast23Provider position=\"top-right\" maxVisible={5}>\r\n * <App />\r\n * </Toast23Provider>\r\n * ```\r\n */\r\n\r\n\"use client\";\r\n\r\nimport { useCallback, useMemo, useReducer } from \"react\";\r\nimport type {\r\n InternalToast,\r\n Toast23ProviderProps,\r\n ToasterContextValue,\r\n ToastOptions,\r\n ToastPosition,\r\n} from \"./types\";\r\nimport type { ReactNode } from \"react\";\r\nimport { ToasterContext, toasterReducer } from \"./context\";\r\nimport { ToastContainer } from \"./toast-container\";\r\nimport { generateId } from \"./utils\";\r\n\r\nconst ALL_POSITIONS: ToastPosition[] = [\r\n \"top-right\",\r\n \"top-left\",\r\n \"top-center\",\r\n \"bottom-right\",\r\n \"bottom-left\",\r\n \"bottom-center\",\r\n];\r\n\r\nexport const Toast23Provider: React.FC<Toast23ProviderProps> = ({\r\n children,\r\n maxVisible = 5,\r\n position: defaultPosition = \"top-right\" as ToastPosition,\r\n duration: defaultDuration = 5000,\r\n}) => {\r\n const [toasts, dispatch] = useReducer(toasterReducer, []);\r\n\r\n // ------ stable callbacks (dispatch is always stable from useReducer) ------\r\n\r\n const addToast = useCallback(\r\n (message: string | ReactNode, options?: ToastOptions & { variant?: any; isCustom?: boolean }): string => {\r\n const id = options?.id ?? generateId();\r\n const toast: InternalToast = {\r\n id,\r\n message,\r\n title: options?.title,\r\n variant: options?.variant ?? \"default\",\r\n duration: options?.duration ?? defaultDuration,\r\n position: options?.position ?? defaultPosition,\r\n dismissible: options?.dismissible ?? true,\r\n removeDelay: options?.removeDelay ?? 1000,\r\n isExiting: false,\r\n createdAt: Date.now(),\r\n version: 0,\r\n isCustom: options?.isCustom,\r\n };\r\n // If an id was provided, upsert (update-or-insert)\r\n if (options?.id) {\r\n dispatch({ type: \"UPSERT\", toast });\r\n } else {\r\n dispatch({ type: \"ADD\", toast });\r\n }\r\n return id;\r\n },\r\n [defaultDuration, defaultPosition],\r\n );\r\n\r\n const updateToast = useCallback(\r\n (\r\n id: string,\r\n updates: Partial<\r\n Pick<\r\n InternalToast,\r\n \"message\" | \"title\" | \"variant\" | \"duration\" | \"dismissible\"\r\n >\r\n >,\r\n ) => {\r\n dispatch({ type: \"UPDATE\", id, updates });\r\n },\r\n [],\r\n );\r\n\r\n const dismissToast = useCallback((id?: string) => {\r\n dispatch({ type: \"DISMISS\", id });\r\n }, []);\r\n\r\n const removeToast = useCallback((id?: string) => {\r\n dispatch({ type: \"REMOVE\", id });\r\n }, []);\r\n\r\n // ------ context value (stable as long as callbacks are stable) ------\r\n\r\n const contextValue: ToasterContextValue = useMemo(\r\n () => ({\r\n addToast,\r\n updateToast,\r\n dismissToast,\r\n removeToast,\r\n config: {\r\n maxVisible,\r\n position: defaultPosition,\r\n duration: defaultDuration,\r\n },\r\n }),\r\n [\r\n addToast,\r\n updateToast,\r\n dismissToast,\r\n removeToast,\r\n maxVisible,\r\n defaultPosition,\r\n defaultDuration,\r\n ],\r\n );\r\n\r\n // ------ group toasts by position ------\r\n\r\n const groupedToasts = useMemo(() => {\r\n const groups: Record<ToastPosition, InternalToast[]> = {\r\n \"top-right\": [],\r\n \"top-left\": [],\r\n \"top-center\": [],\r\n \"bottom-right\": [],\r\n \"bottom-left\": [],\r\n \"bottom-center\": [],\r\n };\r\n for (const t of toasts) {\r\n groups[t.position].push(t);\r\n }\r\n return groups;\r\n }, [toasts]);\r\n\r\n return (\r\n <ToasterContext.Provider value={contextValue}>\r\n {children}\r\n\r\n {/* Render one container per position that has toasts */}\r\n {ALL_POSITIONS.map((pos) =>\r\n groupedToasts[pos].length > 0 ? (\r\n <ToastContainer\r\n key={pos}\r\n position={pos}\r\n toasts={groupedToasts[pos]}\r\n maxVisible={maxVisible}\r\n />\r\n ) : null,\r\n )}\r\n </ToasterContext.Provider>\r\n );\r\n};\r\n\r\nToast23Provider.displayName = \"Toast23Provider\";\r\n","/**\r\n * toast-23 — useToast Hook\r\n *\r\n * Returns a callable `ToastApi` object:\r\n *\r\n * ```ts\r\n * const toast = useToast();\r\n *\r\n * toast(\"Hello!\"); // default variant\r\n * toast.success(\"Done!\"); // success variant\r\n * toast.error(\"Oops\"); // error variant\r\n * toast.promise(fetchData(), { ... }); // promise tracking\r\n * toast.dismiss(id); // manual dismiss\r\n * ```\r\n */\r\n\r\n\"use client\";\r\n\r\nimport { useContext, useMemo } from \"react\";\r\nimport { ToasterContext } from \"./context\";\r\nimport type { ToastApi, ToastOptions, PromiseOptions } from \"./types\";\r\nimport type { ReactNode } from \"react\";\r\n\r\nexport function useToast(): ToastApi {\r\n const ctx = useContext(ToasterContext);\r\n\r\n if (!ctx) {\r\n throw new Error(\r\n \"[toast-23] useToast() must be used inside a <Toast23Provider>. \" +\r\n \"Wrap your application root with <Toast23Provider> to fix this.\",\r\n );\r\n }\r\n\r\n return useMemo(() => {\r\n // Base callable — toast(\"message\", opts?)\r\n const toast = ((message: string | ReactNode, options?: ToastOptions) =>\r\n ctx.addToast(message, options)) as ToastApi;\r\n\r\n // Variant shortcuts\r\n toast.success = (msg, opts) =>\r\n ctx.addToast(msg, { ...opts, variant: \"success\" });\r\n\r\n toast.error = (msg, opts) =>\r\n ctx.addToast(msg, { ...opts, variant: \"error\" });\r\n\r\n toast.warning = (msg, opts) =>\r\n ctx.addToast(msg, { ...opts, variant: \"warning\" });\r\n\r\n toast.info = (msg, opts) => ctx.addToast(msg, { ...opts, variant: \"info\" });\r\n\r\n // Loading shortcut\r\n toast.loading = (msg, opts) =>\r\n ctx.addToast(msg, {\r\n ...opts,\r\n variant: \"loading\" as any,\r\n duration: opts?.duration ?? 0,\r\n dismissible: opts?.dismissible ?? false,\r\n });\r\n\r\n // Custom toast — no default styles\r\n toast.custom = (content, opts) =>\r\n ctx.addToast(content, { ...opts, variant: \"default\", isCustom: true });\r\n\r\n // Dismiss (with optional id — omit to dismiss all)\r\n toast.dismiss = (id?: string) => ctx.dismissToast(id);\r\n\r\n // Remove instantly (with optional id — omit to remove all)\r\n toast.remove = (id?: string) => ctx.removeToast(id);\r\n\r\n // Promise tracking (accepts Promise or () => Promise, optional 3rd arg for toast options)\r\n toast.promise = async <T>(\r\n promiseOrFn: Promise<T> | (() => Promise<T>),\r\n opts: PromiseOptions<T>,\r\n toastOpts?: ToastOptions,\r\n ): Promise<T> => {\r\n const id = ctx.addToast(opts.loading, {\r\n ...toastOpts,\r\n variant: \"loading\" as any,\r\n duration: 0,\r\n dismissible: false,\r\n } as ToastOptions);\r\n\r\n const promise =\r\n typeof promiseOrFn === \"function\" ? promiseOrFn() : promiseOrFn;\r\n\r\n try {\r\n const result = await promise;\r\n const msg =\r\n typeof opts.success === \"function\"\r\n ? opts.success(result)\r\n : opts.success;\r\n ctx.updateToast(id, {\r\n message: msg,\r\n variant: \"success\",\r\n duration: toastOpts?.duration ?? ctx.config.duration,\r\n dismissible: true,\r\n });\r\n return result;\r\n } catch (error) {\r\n const msg =\r\n typeof opts.error === \"function\" ? opts.error(error) : opts.error;\r\n ctx.updateToast(id, {\r\n message: msg,\r\n variant: \"error\",\r\n duration: toastOpts?.duration ?? ctx.config.duration,\r\n dismissible: true,\r\n });\r\n throw error;\r\n }\r\n };\r\n\r\n return toast;\r\n }, [\r\n ctx.addToast,\r\n ctx.updateToast,\r\n ctx.dismissToast,\r\n ctx.removeToast,\r\n ctx.config.duration,\r\n ]);\r\n}\r\n","/**\r\n * toast-23 — Standalone / Imperative API\r\n *\r\n * Use this when you need toast notifications outside of React (Angular, Vue,\r\n * Svelte, vanilla JS, etc.). It internally bootstraps a minimal React root.\r\n *\r\n * ```ts\r\n * import { createToast23 } from \"toast-23\";\r\n *\r\n * const toast = createToast23({ position: \"top-right\" });\r\n *\r\n * toast.success(\"Saved!\");\r\n * toast.error(\"Something went wrong\");\r\n * toast.dismiss(id);\r\n *\r\n * // Cleanup when done (e.g. on app destroy)\r\n * toast.destroy();\r\n * ```\r\n */\r\n\r\nimport * as React from \"react\";\r\nimport { createRoot, type Root } from \"react-dom/client\";\r\nimport { Toast23Provider } from \"./provider\";\r\nimport { useToast } from \"./use-toast\";\r\nimport type {\r\n ToastPosition,\r\n ToastOptions,\r\n PromiseOptions,\r\n ToastApi,\r\n} from \"./types\";\r\nimport type { ReactNode } from \"react\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface StandaloneOptions {\r\n /** Where on screen toasts appear. @default \"top-right\" */\r\n position?: ToastPosition;\r\n /** Max simultaneous toasts. @default 5 */\r\n maxVisible?: number;\r\n /** Default auto-dismiss duration in ms. @default 5000 */\r\n duration?: number;\r\n}\r\n\r\nexport interface StandaloneToastApi {\r\n /** Show a default toast. Returns the toast id. */\r\n (message: string | ReactNode, options?: ToastOptions): string;\r\n /** Show a success toast. */\r\n success: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Show an error toast. */\r\n error: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Show a warning toast. */\r\n warning: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Show an info toast. */\r\n info: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Show a loading toast. Returns the toast id for later update. */\r\n loading: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Show a custom toast with JSX content and no default styles. */\r\n custom: (\r\n content: ReactNode,\r\n options?: Omit<ToastOptions, \"variant\">,\r\n ) => string;\r\n /** Track an async operation with loading → success / error transitions. */\r\n promise: <T>(\r\n promise: Promise<T> | (() => Promise<T>),\r\n options: PromiseOptions<T>,\r\n toastOptions?: ToastOptions,\r\n ) => Promise<T>;\r\n /** Manually dismiss a toast by id. Omit id to dismiss all. */\r\n dismiss: (id?: string) => void;\r\n /** Instantly remove a toast from DOM (no exit animation). Omit id to remove all. */\r\n remove: (id?: string) => void;\r\n /** Unmount the React root and remove the container from the DOM. */\r\n destroy: () => void;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Bridge component — captures the useToast API and passes it out\r\n// ---------------------------------------------------------------------------\r\n\r\nlet _resolveApi: ((api: ToastApi) => void) | null = null;\r\n\r\nfunction Bridge() {\r\n const api = useToast();\r\n\r\n // Resolve the promise on first render; update the ref on every render\r\n // so the external caller always has the latest stable API reference.\r\n React.useEffect(() => {\r\n if (_resolveApi) {\r\n _resolveApi(api);\r\n _resolveApi = null;\r\n }\r\n }, [api]);\r\n\r\n // Also store on ref for synchronous access after first mount\r\n\r\n return null;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Factory\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Create a standalone toast API that works outside of React.\r\n *\r\n * Internally mounts a tiny React tree (provider + bridge) into a hidden\r\n * container. Returns a callable toast object with `.success()`, `.error()`, etc.\r\n *\r\n * Call `.destroy()` when your application unmounts to clean up.\r\n */\r\nexport function createToast23(\r\n options: StandaloneOptions = {},\r\n): StandaloneToastApi {\r\n const { position = \"top-right\", maxVisible = 5, duration = 5000 } = options;\r\n\r\n // Create a hidden container\r\n const container = document.createElement(\"div\");\r\n container.setAttribute(\"data-toast23-standalone\", \"\");\r\n container.style.display = \"contents\"; // invisible wrapper\r\n document.body.appendChild(container);\r\n\r\n // We need to wait for React to render before the API is available.\r\n // Use a promise + queue approach so calls before mount are buffered.\r\n let root: Root | null = createRoot(container);\r\n\r\n const apiReady = new Promise<ToastApi>((resolve) => {\r\n _resolveApi = resolve;\r\n });\r\n\r\n // Queue for calls made before React has mounted\r\n type QueuedCall = { method: string; args: unknown[] };\r\n const queue: QueuedCall[] = [];\r\n let resolvedApi: ToastApi | null = null;\r\n\r\n // Flush queued calls once the API is ready\r\n apiReady.then((api) => {\r\n resolvedApi = api;\r\n for (const call of queue) {\r\n if (call.method === \"__call__\") {\r\n (api as any)(...call.args);\r\n } else {\r\n (api as any)[call.method](...call.args);\r\n }\r\n }\r\n queue.length = 0;\r\n });\r\n\r\n // Mount React tree\r\n root.render(\r\n React.createElement(\r\n Toast23Provider,\r\n { position, maxVisible, duration } as any,\r\n React.createElement(Bridge),\r\n ),\r\n );\r\n\r\n // Build the proxy API\r\n const proxyCall = (method: string, ...args: unknown[]): any => {\r\n if (resolvedApi) {\r\n return (resolvedApi as any)[method](...args);\r\n }\r\n queue.push({ method, args });\r\n return \"queued\";\r\n };\r\n\r\n const toast = ((message: string | ReactNode, opts?: ToastOptions) => {\r\n if (resolvedApi) return resolvedApi(message, opts);\r\n queue.push({ method: \"__call__\", args: [message, opts] });\r\n return \"queued\";\r\n }) as StandaloneToastApi;\r\n\r\n toast.success = (msg, opts) => proxyCall(\"success\", msg, opts);\r\n toast.error = (msg, opts) => proxyCall(\"error\", msg, opts);\r\n toast.warning = (msg, opts) => proxyCall(\"warning\", msg, opts);\r\n toast.info = (msg, opts) => proxyCall(\"info\", msg, opts);\r\n toast.loading = (msg, opts) => proxyCall(\"loading\", msg, opts);\r\n toast.custom = (content, opts) => proxyCall(\"custom\", content, opts);\r\n toast.dismiss = (id?) => proxyCall(\"dismiss\", id);\r\n toast.remove = (id?) => proxyCall(\"remove\", id);\r\n\r\n toast.promise = (promise, opts, toastOpts?) => {\r\n if (resolvedApi) return resolvedApi.promise(promise, opts, toastOpts);\r\n // For promises, we need to wait for the API\r\n return apiReady.then((api) => api.promise(promise, opts, toastOpts));\r\n };\r\n\r\n toast.destroy = () => {\r\n if (root) {\r\n root.unmount();\r\n root = null;\r\n }\r\n container.remove();\r\n resolvedApi = null;\r\n };\r\n\r\n return toast;\r\n}\r\n"],"names":["ToasterContext","createContext","toasterReducer","state","action","t","CheckCircleIcon","props","jsxs","jsx","XCircleIcon","AlertTriangleIcon","InfoIcon","XIcon","SpinnerIcon","counter","generateId","cx","args","variantIcon","EXIT_DURATION","MIN_REFILL_DURATION","ToastItem","React","toast","onDismiss","onRemove","hasEntered","setHasEntered","useState","useEffect","raf","delay","timer","isPaused","setIsPaused","remainingRef","useRef","startRef","progress","setProgress","progressTransition","setProgressTransition","rafRef","elapsed","refillDuration","remaining","handleMouseEnter","useCallback","handleMouseLeave","Icon","ToastContainer","position","toasts","maxVisible","ctx","useContext","active","exiting","visible","queuedCount","ALL_POSITIONS","Toast23Provider","children","defaultPosition","defaultDuration","dispatch","useReducer","addToast","message","options","id","updateToast","updates","dismissToast","removeToast","contextValue","useMemo","groupedToasts","groups","pos","useToast","msg","opts","content","promiseOrFn","toastOpts","promise","result","error","_resolveApi","Bridge","api","createToast23","duration","container","root","createRoot","apiReady","resolve","queue","resolvedApi","call","proxyCall","method"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/context.tsx","../src/icons.tsx","../src/utils.ts","../src/toast-item.tsx","../src/toast-container.tsx","../src/provider.tsx","../src/use-toast.ts","../src/standalone.ts"],"sourcesContent":["/**\r\n * toast-23 — React Context & Reducer\r\n */\r\n\r\nimport { createContext } from \"react\";\r\nimport type {\r\n InternalToast,\r\n ToasterAction,\r\n ToasterContextValue,\r\n} from \"./types\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Context — consumed by useToast() and internal components\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const ToasterContext = createContext<ToasterContextValue | null>(null);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Reducer — pure state transitions for the toast queue\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function toasterReducer(\r\n state: InternalToast[],\r\n action: ToasterAction,\r\n): InternalToast[] {\r\n switch (action.type) {\r\n case \"ADD\":\r\n return [...state, action.toast];\r\n\r\n case \"UPSERT\": {\r\n const exists = state.some((t) => t.id === action.toast.id);\r\n if (exists) {\r\n return state.map((t) =>\r\n t.id === action.toast.id\r\n ? {\r\n ...t,\r\n ...action.toast,\r\n version: t.version + 1,\r\n isExiting: false,\r\n }\r\n : t,\r\n );\r\n }\r\n return [...state, action.toast];\r\n }\r\n\r\n case \"UPDATE\":\r\n return state.map((t) =>\r\n t.id === action.id\r\n ? {\r\n ...t,\r\n ...action.updates,\r\n // Bump version so progress bar restarts\r\n version: t.version + 1,\r\n // If the toast was exiting, cancel exit on update\r\n isExiting: false,\r\n }\r\n : t,\r\n );\r\n\r\n case \"DISMISS\":\r\n // Omit id → dismiss all\r\n if (!action.id) {\r\n return state.map((t) => ({ ...t, isExiting: true }));\r\n }\r\n return state.map((t) =>\r\n t.id === action.id ? { ...t, isExiting: true } : t,\r\n );\r\n\r\n case \"REMOVE\":\r\n // Omit id → remove all instantly\r\n if (!action.id) return [];\r\n return state.filter((t) => t.id !== action.id);\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","/**\r\n * toast-23 — Inline SVG Icons (Filled style)\r\n *\r\n * Solid colored circles/triangles with white inner symbols, designed to be used with the default styles. Each icon inherits `currentColor` so it can be colored via CSS.\r\n */\r\n\r\nimport type { SVGProps, FC } from \"react\";\r\n\r\ntype IconProps = SVGProps<SVGSVGElement>;\r\n\r\n/** Green filled circle with white checkmark */\r\nexport const CheckCircleIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <circle cx={12} cy={12} r={10} fill=\"currentColor\" />\r\n <path\r\n d=\"M8 12.5l2.5 2.5 5-5\"\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n fill=\"none\"\r\n />\r\n </svg>\r\n);\r\n\r\n/** Red filled circle with white exclamation */\r\nexport const XCircleIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <circle cx={12} cy={12} r={10} fill=\"currentColor\" />\r\n <line\r\n x1={12}\r\n y1={8}\r\n x2={12}\r\n y2={13}\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n <circle cx={12} cy={16} r={1} fill=\"#fff\" />\r\n </svg>\r\n);\r\n\r\n/** Yellow filled triangle with white exclamation */\r\nexport const AlertTriangleIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <path\r\n d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"\r\n fill=\"currentColor\"\r\n />\r\n <line\r\n x1={12}\r\n y1={9.5}\r\n x2={12}\r\n y2={14}\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n <circle cx={12} cy={17} r={1} fill=\"#fff\" />\r\n </svg>\r\n);\r\n\r\n/** Blue filled circle with white \"i\" */\r\nexport const InfoIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n fill=\"none\"\r\n {...props}\r\n >\r\n <circle cx={12} cy={12} r={10} fill=\"currentColor\" />\r\n <line\r\n x1={12}\r\n y1={11}\r\n x2={12}\r\n y2={16}\r\n stroke=\"#fff\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n />\r\n <circle cx={12} cy={8} r={1} fill=\"#fff\" />\r\n </svg>\r\n);\r\n\r\n/** Thin X icon for dismiss button */\r\nexport const XIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n width=\"0.875em\"\r\n height=\"0.875em\"\r\n {...props}\r\n >\r\n <line x1={18} y1={6} x2={6} y2={18} />\r\n <line x1={6} y1={6} x2={18} y2={18} />\r\n </svg>\r\n);\r\n\r\n/** CSS-only loading spinner */\r\nexport const SpinnerIcon: FC<IconProps> = (props: IconProps) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n width=\"1.25em\"\r\n height=\"1.25em\"\r\n className=\"toast23-spinner\"\r\n {...props}\r\n >\r\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\r\n </svg>\r\n);\r\n","/**\r\n * toast-23 — Utility helpers\r\n */\r\n\r\nlet counter = 0;\r\n\r\n/**\r\n * Generates a unique toast id.\r\n * Works in SSR (no dependency on `crypto`).\r\n */\r\nexport function generateId(): string {\r\n return `t23-${++counter}-${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Deterministic class-name builder (replaces clsx dependency).\r\n */\r\nexport function cx(...args: (string | false | null | undefined | 0)[]): string {\r\n return args.filter(Boolean).join(\" \");\r\n}\r\n","/**\r\n * toast-23 — Individual Toast Component\r\n *\r\n * Manages its own enter / exit CSS transitions and auto-dismiss timer.\r\n * Progress bar is JS-driven so it can reverse (refill) on hover.\r\n */\r\n\r\n\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { InternalToast } from \"./types\";\r\nimport {\r\n CheckCircleIcon,\r\n XCircleIcon,\r\n AlertTriangleIcon,\r\n InfoIcon,\r\n SpinnerIcon,\r\n XIcon,\r\n} from \"./icons\";\r\nimport { cx } from \"./utils\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Icon map\r\n// ---------------------------------------------------------------------------\r\n\r\nconst variantIcon: Record<string, React.FC<React.SVGProps<SVGSVGElement>>> = {\r\n success: CheckCircleIcon,\r\n error: XCircleIcon,\r\n warning: AlertTriangleIcon,\r\n info: InfoIcon,\r\n default: InfoIcon,\r\n loading: SpinnerIcon,\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Component\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ToastItemProps {\r\n toast: InternalToast;\r\n onDismiss: (id: string) => void;\r\n onRemove: (id: string) => void;\r\n}\r\n\r\nconst EXIT_DURATION = 300; // ms — must match CSS transition duration\r\n// const MIN_REFILL_DURATION = 200; // ms — minimum refill time so very short hovers aren't instant\r\n\r\nexport const ToastItem: React.FC<ToastItemProps> = React.memo(\r\n ({ toast, onDismiss, onRemove }) => {\r\n // ----- animation state -----\r\n const [hasEntered, setHasEntered] = useState(false);\r\n\r\n // Trigger enter transition on next frame\r\n useEffect(() => {\r\n const raf = requestAnimationFrame(() => setHasEntered(true));\r\n return () => cancelAnimationFrame(raf);\r\n }, []);\r\n\r\n // When the provider marks the toast as exiting, it waits for the CSS\r\n // transition to finish then actually remove it from state.\r\n useEffect(() => {\r\n if (!toast.isExiting) return;\r\n const delay = toast.removeDelay ?? EXIT_DURATION;\r\n const timer = setTimeout(() => onRemove(toast.id), delay);\r\n return () => clearTimeout(timer);\r\n }, [toast.isExiting, toast.id, toast.removeDelay, onRemove]);\r\n\r\n // ----- auto-dismiss timer with hover-pause -----\r\n const [isPaused, setIsPaused] = useState(false);\r\n const remainingRef = useRef(toast.duration);\r\n // const startRef = useRef(0);\r\n\r\n // ----- JS-driven progress bar -----\r\n // progress: 100 = full, 0 = empty\r\n const [progress, setProgress] = useState(100);\r\n // transition duration for the progress bar\r\n const [progressTransition, setProgressTransition] = useState(\"none\");\r\n // const rafRef = useRef<number>(0);\r\n\r\n // Reset remaining time when version changes (e.g. promise resolved)\r\n useEffect(() => {\r\n remainingRef.current = toast.duration;\r\n setProgress(100);\r\n setProgressTransition(\"none\");\r\n }, [toast.version, toast.duration]);\r\n\r\n useEffect(() => {\r\n // Don't auto-dismiss: persistent, loading, still entering, or already exiting\r\n if (\r\n toast.duration <= 0 ||\r\n toast.variant === \"loading\" ||\r\n !hasEntered ||\r\n toast.isExiting\r\n )\r\n return;\r\n\r\n // if (isPaused) {\r\n // // How long the bar was shrinking before hover\r\n // const elapsed = Date.now() - startRef.current;\r\n // // Snapshot remaining time\r\n // remainingRef.current = Math.max(0, remainingRef.current - elapsed);\r\n\r\n // // Reverse at the same speed it was shrinking (proportional duration)\r\n // const refillDuration = Math.max(MIN_REFILL_DURATION, elapsed);\r\n // setProgressTransition(`width ${refillDuration}ms ease-out`);\r\n // setProgress(100);\r\n // return;\r\n // }\r\n\r\n // // Start shrinking\r\n // startRef.current = Date.now();\r\n // const remaining = remainingRef.current;\r\n\r\n // Set transition to match remaining time and shrink to 0\r\n // Use rAF to ensure the refill transition has settled before starting shrink\r\n // rafRef.current = requestAnimationFrame(() => {\r\n // setProgressTransition(`width ${remaining}ms linear`);\r\n // setProgress(0);\r\n // });\r\n\r\n // const timer = setTimeout(() => {\r\n // onDismiss(toast.id);\r\n // }, remaining);\r\n\r\n // return () => {\r\n // clearTimeout(timer);\r\n // cancelAnimationFrame(rafRef.current);\r\n // };\r\n // }, [\r\n // isPaused,\r\n // hasEntered,\r\n // toast.isExiting,\r\n // toast.duration,\r\n // toast.variant,\r\n // toast.id,\r\n // toast.version,\r\n // onDismiss,\r\n // ]);\r\n if (isPaused) {\r\n // refill instantly\r\n setProgressTransition(\"width 200ms ease-out\");\r\n setProgress(100);\r\n return;\r\n }\r\n\r\n // restart shrink animation from full\r\n setProgress(100);\r\n requestAnimationFrame(() => {\r\n setProgressTransition(`width ${toast.duration}ms linear`);\r\n setProgress(0);\r\n });\r\n\r\n const timer = setTimeout(() => {\r\n onDismiss(toast.id);\r\n }, toast.duration);\r\n\r\n return () => clearTimeout(timer);\r\n}, [\r\n isPaused,\r\n toast.duration,\r\n toast.variant,\r\n toast.isExiting,\r\n toast.id,\r\n hasEntered,\r\n onDismiss,\r\n]);\r\n\r\n // ----- handlers -----\r\n const handleMouseEnter = useCallback(() => setIsPaused(true), []);\r\n const handleMouseLeave = useCallback(() => setIsPaused(false), []);\r\n\r\n // ----- render -----\r\n const Icon = variantIcon[toast.variant] ?? InfoIcon;\r\n\r\n // Custom toast — render raw content with no default chrome\r\n if (toast.isCustom) {\r\n return (\r\n <div\r\n className={cx(\r\n \"toast23-item toast23-item--custom\",\r\n !hasEntered && \"toast23-item--entering\",\r\n toast.isExiting && \"toast23-item--exiting\",\r\n )}\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"true\"\r\n onMouseEnter={handleMouseEnter}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n {toast.message}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n \"toast23-item\",\r\n `toast23-item--${toast.variant}`,\r\n !hasEntered && \"toast23-item--entering\",\r\n toast.isExiting && \"toast23-item--exiting\",\r\n )}\r\n role=\"alert\"\r\n aria-live={toast.variant === \"error\" ? \"assertive\" : \"polite\"}\r\n aria-atomic=\"true\"\r\n onMouseEnter={handleMouseEnter}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n {/* Icon */}\r\n <span className={cx(\"toast23-icon\", `toast23-icon--${toast.variant}`)}>\r\n <Icon />\r\n </span>\r\n\r\n {/* Content */}\r\n <div className=\"toast23-content\">\r\n {toast.title && <div className=\"toast23-title\">{toast.title}</div>}\r\n <div\r\n className={cx(\r\n \"toast23-message\",\r\n toast.title && \"toast23-message--with-title\",\r\n )}\r\n >\r\n {toast.message}\r\n </div>\r\n </div>\r\n\r\n {/* Dismiss button */}\r\n {toast.dismissible && (\r\n <button\r\n type=\"button\"\r\n className=\"toast23-dismiss\"\r\n onClick={() => onDismiss(toast.id)}\r\n aria-label=\"Dismiss notification\"\r\n >\r\n <XIcon />\r\n </button>\r\n )}\r\n\r\n {/* Progress bar — JS-driven width for hover reversal */}\r\n {toast.duration > 0 && toast.variant !== \"loading\" && (\r\n <div\r\n className={cx(\r\n \"toast23-progress\",\r\n `toast23-progress--${toast.variant}`,\r\n )}\r\n style={{\r\n width: `${progress}%`,\r\n transition: progressTransition,\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nToastItem.displayName = \"ToastItem\";\r\n","/**\r\n * toast-23 — Positioned Toast Container\r\n *\r\n * Renders a group of toasts for a given screen position.\r\n * Handles queue logic: only `maxVisible` non-exiting toasts are shown,\r\n * plus any currently animating-out toasts.\r\n */\r\n\r\n\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { useContext } from \"react\";\r\nimport type { InternalToast, ToastPosition } from \"./types\";\r\nimport { ToasterContext } from \"./context\";\r\nimport { ToastItem } from \"./toast-item\";\r\nimport { cx } from \"./utils\";\r\n\r\ninterface ToastContainerProps {\r\n position: ToastPosition;\r\n toasts: InternalToast[];\r\n maxVisible: number;\r\n}\r\n\r\nexport const ToastContainer: React.FC<ToastContainerProps> = React.memo(\r\n ({ position, toasts, maxVisible }: ToastContainerProps) => {\r\n const ctx = useContext(ToasterContext);\r\n if (!ctx) return null;\r\n\r\n // Separate actives vs. exiting toasts\r\n const active = toasts.filter((t) => !t.isExiting);\r\n const exiting = toasts.filter((t) => t.isExiting);\r\n\r\n // Only shows up to maxVisible active toasts, plus all currently exiting\r\n const visible = [...active.slice(0, maxVisible), ...exiting];\r\n\r\n if (visible.length === 0) return null;\r\n\r\n // Queue count for optional badge\r\n const queuedCount = Math.max(0, active.length - maxVisible);\r\n\r\n return (\r\n <div\r\n className={cx(\"toast23-container\", `toast23-container--${position}`)}\r\n aria-label=\"Notifications\"\r\n role=\"region\"\r\n >\r\n {visible.map((toast) => (\r\n <ToastItem\r\n key={toast.id}\r\n toast={toast}\r\n onDismiss={ctx.dismissToast}\r\n onRemove={ctx.removeToast}\r\n />\r\n ))}\r\n {queuedCount > 0 && (\r\n <div className=\"toast23-queue-badge\" aria-live=\"polite\">\r\n +{queuedCount} more\r\n </div>\r\n )}\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nToastContainer.displayName = \"ToastContainer\";\r\n","/**\r\n * toast-23 — Toast23Provider\r\n *\r\n * Wrap your application with this provider to enable toast notifications.\r\n *\r\n * ```tsx\r\n * <Toast23Provider position=\"top-right\" maxVisible={5}>\r\n * <App />\r\n * </Toast23Provider>\r\n * ```\r\n */\r\n\r\n\"use client\";\r\n\r\nimport { useCallback, useMemo, useReducer } from \"react\";\r\nimport type {\r\n InternalToast,\r\n Toast23ProviderProps,\r\n ToasterContextValue,\r\n ToastOptions,\r\n ToastPosition,\r\n} from \"./types\";\r\nimport type { ReactNode } from \"react\";\r\nimport { ToasterContext, toasterReducer } from \"./context\";\r\nimport { ToastContainer } from \"./toast-container\";\r\nimport { generateId } from \"./utils\";\r\n\r\nconst ALL_POSITIONS: ToastPosition[] = [\r\n \"top-right\",\r\n \"top-left\",\r\n \"top-center\",\r\n \"bottom-right\",\r\n \"bottom-left\",\r\n \"bottom-center\",\r\n];\r\n\r\nexport const Toast23Provider: React.FC<Toast23ProviderProps> = ({\r\n children,\r\n maxVisible = 5,\r\n position: defaultPosition = \"top-right\" as ToastPosition,\r\n duration: defaultDuration = 5000,\r\n}) => {\r\n const [toasts, dispatch] = useReducer(toasterReducer, []);\r\n\r\n // ------ stable callbacks (dispatch is always stable from useReducer) ------\r\n\r\n const addToast = useCallback(\r\n (message: string | ReactNode, options?: ToastOptions & { variant?: any; isCustom?: boolean }): string => {\r\n const id = options?.id ?? generateId();\r\n const toast: InternalToast = {\r\n id,\r\n message,\r\n title: options?.title,\r\n variant: options?.variant ?? \"default\",\r\n duration: options?.duration ?? defaultDuration,\r\n position: options?.position ?? defaultPosition,\r\n dismissible: options?.dismissible ?? true,\r\n removeDelay: options?.removeDelay ?? 1000,\r\n isExiting: false,\r\n createdAt: Date.now(),\r\n version: 0,\r\n isCustom: options?.isCustom,\r\n };\r\n // If an id is provided, upsert (update-or-insert)\r\n if (options?.id) {\r\n dispatch({ type: \"UPSERT\", toast });\r\n } else {\r\n dispatch({ type: \"ADD\", toast });\r\n }\r\n return id;\r\n },\r\n [defaultDuration, defaultPosition],\r\n );\r\n\r\n const updateToast = useCallback(\r\n (\r\n id: string,\r\n updates: Partial<\r\n Pick<\r\n InternalToast,\r\n \"message\" | \"title\" | \"variant\" | \"duration\" | \"dismissible\"\r\n >\r\n >,\r\n ) => {\r\n dispatch({ type: \"UPDATE\", id, updates });\r\n },\r\n [],\r\n );\r\n\r\n const dismissToast = useCallback((id?: string) => {\r\n dispatch({ type: \"DISMISS\", id });\r\n }, []);\r\n\r\n const removeToast = useCallback((id?: string) => {\r\n dispatch({ type: \"REMOVE\", id });\r\n }, []);\r\n\r\n // ------ context value (stable as long as callbacks are stable) ------\r\n\r\n const contextValue: ToasterContextValue = useMemo(\r\n () => ({\r\n addToast,\r\n updateToast,\r\n dismissToast,\r\n removeToast,\r\n config: {\r\n maxVisible,\r\n position: defaultPosition,\r\n duration: defaultDuration,\r\n },\r\n }),\r\n [\r\n addToast,\r\n updateToast,\r\n dismissToast,\r\n removeToast,\r\n maxVisible,\r\n defaultPosition,\r\n defaultDuration,\r\n ],\r\n );\r\n\r\n // ------ group toasts by position ------\r\n\r\n const groupedToasts = useMemo(() => {\r\n const groups: Record<ToastPosition, InternalToast[]> = {\r\n \"top-right\": [],\r\n \"top-left\": [],\r\n \"top-center\": [],\r\n \"bottom-right\": [],\r\n \"bottom-left\": [],\r\n \"bottom-center\": [],\r\n };\r\n for (const t of toasts) {\r\n groups[t.position].push(t);\r\n }\r\n return groups;\r\n }, [toasts]);\r\n\r\n return (\r\n <ToasterContext.Provider value={contextValue}>\r\n {children}\r\n\r\n {/* Render one container per position that has toasts */}\r\n {ALL_POSITIONS.map((pos) =>\r\n groupedToasts[pos].length > 0 ? (\r\n <ToastContainer\r\n key={pos}\r\n position={pos}\r\n toasts={groupedToasts[pos]}\r\n maxVisible={maxVisible}\r\n />\r\n ) : null,\r\n )}\r\n </ToasterContext.Provider>\r\n );\r\n};\r\n\r\nToast23Provider.displayName = \"Toast23Provider\";\r\n","/**\r\n * toast-23 — useToast Hook\r\n *\r\n * Returns a callable `ToastApi` object:\r\n *\r\n * ```ts\r\n * const toast = useToast();\r\n *\r\n * toast(\"Hello!\"); // default variant\r\n * toast.success(\"Done!\"); // success variant\r\n * toast.error(\"Oops\"); // error variant\r\n * toast.promise(fetchData(), { ... }); // promise tracking\r\n * toast.dismiss(id); // manual dismiss\r\n * ```\r\n */\r\n\r\n\"use client\";\r\n\r\nimport { useContext, useMemo } from \"react\";\r\nimport { ToasterContext } from \"./context\";\r\nimport type { ToastApi, ToastOptions, PromiseOptions } from \"./types\";\r\nimport type { ReactNode } from \"react\";\r\n\r\nexport function useToast(): ToastApi {\r\n const ctx = useContext(ToasterContext);\r\n\r\n if (!ctx) {\r\n throw new Error(\r\n \"[toast-23] useToast() must be used inside a <Toast23Provider>. \" +\r\n \"Wrap your application root with <Toast23Provider> to fix this.\",\r\n );\r\n }\r\n\r\n return useMemo(() => {\r\n // Base callable — toast(\"message\", opts?)\r\n const toast = ((message: string | ReactNode, options?: ToastOptions) =>\r\n ctx.addToast(message, options)) as ToastApi;\r\n\r\n // Variant shortcuts\r\n toast.success = (msg, opts) =>\r\n ctx.addToast(msg, { ...opts, variant: \"success\" });\r\n\r\n toast.error = (msg, opts) =>\r\n ctx.addToast(msg, { ...opts, variant: \"error\" });\r\n\r\n toast.warning = (msg, opts) =>\r\n ctx.addToast(msg, { ...opts, variant: \"warning\" });\r\n\r\n toast.info = (msg, opts) => ctx.addToast(msg, { ...opts, variant: \"info\" });\r\n\r\n // Loading shortcut\r\n toast.loading = (msg, opts) =>\r\n ctx.addToast(msg, {\r\n ...opts,\r\n variant: \"loading\" as any,\r\n duration: opts?.duration ?? 0,\r\n dismissible: opts?.dismissible ?? false,\r\n });\r\n\r\n // Custom toast — no default styles\r\n toast.custom = (content, opts) =>\r\n ctx.addToast(content, { ...opts, variant: \"default\", isCustom: true });\r\n\r\n // Dismiss (with optional id — omit to dismiss all)\r\n toast.dismiss = (id?: string) => ctx.dismissToast(id);\r\n\r\n // Remove instantly (with optional id — omit to remove all)\r\n toast.remove = (id?: string) => ctx.removeToast(id);\r\n\r\n // Promise tracking (accepts Promise or () => Promise, optional 3rd arg for toast options)\r\n toast.promise = async <T>(\r\n promiseOrFn: Promise<T> | (() => Promise<T>),\r\n opts: PromiseOptions<T>,\r\n toastOpts?: ToastOptions,\r\n ): Promise<T> => {\r\n const id = ctx.addToast(opts.loading, {\r\n ...toastOpts,\r\n variant: \"loading\" as any,\r\n duration: 0,\r\n dismissible: false,\r\n } as ToastOptions);\r\n\r\n const promise =\r\n typeof promiseOrFn === \"function\" ? promiseOrFn() : promiseOrFn;\r\n\r\n try {\r\n const result = await promise;\r\n const msg =\r\n typeof opts.success === \"function\"\r\n ? opts.success(result)\r\n : opts.success;\r\n ctx.updateToast(id, {\r\n message: msg,\r\n variant: \"success\",\r\n duration: toastOpts?.duration ?? ctx.config.duration,\r\n dismissible: true,\r\n });\r\n return result;\r\n } catch (error) {\r\n const msg =\r\n typeof opts.error === \"function\" ? opts.error(error) : opts.error;\r\n ctx.updateToast(id, {\r\n message: msg,\r\n variant: \"error\",\r\n duration: toastOpts?.duration ?? ctx.config.duration,\r\n dismissible: true,\r\n });\r\n throw error;\r\n }\r\n };\r\n\r\n return toast;\r\n }, [\r\n ctx.addToast,\r\n ctx.updateToast,\r\n ctx.dismissToast,\r\n ctx.removeToast,\r\n ctx.config.duration,\r\n ]);\r\n}\r\n","/**\r\n * toast-23 — Standalone / Imperative API\r\n *\r\n * Used when you need toast notifications outside of React (Angular, Vue,\r\n * Svelte, vanilla JS, etc.). It internally bootstraps a minimal React root.\r\n *\r\n * ```ts\r\n * import { createToast23 } from \"toast-23\";\r\n *\r\n * const toast = createToast23({ position: \"top-right\" });\r\n *\r\n * toast.success(\"Saved!\");\r\n * toast.error(\"Something went wrong\");\r\n * toast.dismiss(id);\r\n *\r\n * // Cleanup when done (e.g. on app destroy)\r\n * toast.destroy();\r\n * ```\r\n */\r\n\r\nimport * as React from \"react\";\r\nimport { createRoot, type Root } from \"react-dom/client\";\r\nimport { Toast23Provider } from \"./provider\";\r\nimport { useToast } from \"./use-toast\";\r\nimport type {\r\n ToastPosition,\r\n ToastOptions,\r\n PromiseOptions,\r\n ToastApi,\r\n} from \"./types\";\r\nimport type { ReactNode } from \"react\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface StandaloneOptions {\r\n /** Where on screen toasts appear. @default \"top-right\" */\r\n position?: ToastPosition;\r\n /** Max simultaneous toasts. @default 5 */\r\n maxVisible?: number;\r\n /** Default auto-dismiss duration in ms. @default 5000 */\r\n duration?: number;\r\n}\r\n\r\nexport interface StandaloneToastApi {\r\n /** Shows a default toast. Returns the toast id. */\r\n (message: string | ReactNode, options?: ToastOptions): string;\r\n /** Shows a success toast. */\r\n success: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Shows an error toast. */\r\n error: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Shows a warning toast. */\r\n warning: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Shows an info toast. */\r\n info: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Shows a loading toast. Returns the toast id for later update. */\r\n loading: (message: string, options?: Omit<ToastOptions, \"variant\">) => string;\r\n /** Shows a custom toast with JSX content and no default styles. */\r\n custom: (\r\n content: ReactNode,\r\n options?: Omit<ToastOptions, \"variant\">,\r\n ) => string;\r\n /** Track an async operation with loading → success / error transitions. */\r\n promise: <T>(\r\n promise: Promise<T> | (() => Promise<T>),\r\n options: PromiseOptions<T>,\r\n toastOptions?: ToastOptions,\r\n ) => Promise<T>;\r\n /** Manually dismisses a toast by id. Omits id to dismiss all. */\r\n dismiss: (id?: string) => void;\r\n /** Instantly removes a toast from DOM (no exit animation). Omits id to remove all. */\r\n remove: (id?: string) => void;\r\n /** Unmounts the React root and removes the container from the DOM. */\r\n destroy: () => void;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Bridge component — captures the useToast API and passes it out\r\n// ---------------------------------------------------------------------------\r\n\r\nlet _resolveApi: ((api: ToastApi) => void) | null = null;\r\n\r\nfunction Bridge() {\r\n const api = useToast();\r\n\r\n // Resolves the promise on first render; update the ref on every render\r\n // so the external caller always has the latest stable API reference.\r\n React.useEffect(() => {\r\n if (_resolveApi) {\r\n _resolveApi(api);\r\n _resolveApi = null;\r\n }\r\n }, [api]);\r\n\r\n // Also stores on ref for synchronous access after first mount\r\n\r\n return null;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Factory\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n *\r\n * Internally mounts a tiny React tree (provider + bridge) into a hidden\r\n * container. Returns a callable toast object with `.success()`, `.error()`, etc.\r\n *\r\n * Call `.destroy()` when your application unmounts to clean up.\r\n */\r\nexport function createToast23(\r\n options: StandaloneOptions = {},\r\n): StandaloneToastApi {\r\n const { position = \"top-right\", maxVisible = 5, duration = 5000 } = options;\r\n\r\n // Creates a hidden container\r\n const container = document.createElement(\"div\");\r\n container.setAttribute(\"data-toast23-standalone\", \"\");\r\n container.style.display = \"contents\"; // invisible wrapper\r\n document.body.appendChild(container);\r\n\r\n //Waits for React to render before the API is available.\r\n // Use of promise + queue approach so calls before mount are buffered.\r\n let root: Root | null = createRoot(container);\r\n\r\n const apiReady = new Promise<ToastApi>((resolve) => {\r\n _resolveApi = resolve;\r\n });\r\n\r\n // Queue for calls made before React has mounted\r\n type QueuedCall = { method: string; args: unknown[] };\r\n const queue: QueuedCall[] = [];\r\n let resolvedApi: ToastApi | null = null;\r\n\r\n // Flushes queued calls once the API is ready\r\n apiReady.then((api) => {\r\n resolvedApi = api;\r\n for (const call of queue) {\r\n if (call.method === \"__call__\") {\r\n (api as any)(...call.args);\r\n } else {\r\n (api as any)[call.method](...call.args);\r\n }\r\n }\r\n queue.length = 0;\r\n });\r\n\r\n // Mounts React tree\r\n root.render(\r\n React.createElement(\r\n Toast23Provider,\r\n { position, maxVisible, duration } as any,\r\n React.createElement(Bridge),\r\n ),\r\n );\r\n\r\n // Builds the proxy API\r\n const proxyCall = (method: string, ...args: unknown[]): any => {\r\n if (resolvedApi) {\r\n return (resolvedApi as any)[method](...args);\r\n }\r\n queue.push({ method, args });\r\n return \"queued\";\r\n };\r\n\r\n const toast = ((message: string | ReactNode, opts?: ToastOptions) => {\r\n if (resolvedApi) return resolvedApi(message, opts);\r\n queue.push({ method: \"__call__\", args: [message, opts] });\r\n return \"queued\";\r\n }) as StandaloneToastApi;\r\n\r\n toast.success = (msg, opts) => proxyCall(\"success\", msg, opts);\r\n toast.error = (msg, opts) => proxyCall(\"error\", msg, opts);\r\n toast.warning = (msg, opts) => proxyCall(\"warning\", msg, opts);\r\n toast.info = (msg, opts) => proxyCall(\"info\", msg, opts);\r\n toast.loading = (msg, opts) => proxyCall(\"loading\", msg, opts);\r\n toast.custom = (content, opts) => proxyCall(\"custom\", content, opts);\r\n toast.dismiss = (id?) => proxyCall(\"dismiss\", id);\r\n toast.remove = (id?) => proxyCall(\"remove\", id);\r\n\r\n toast.promise = (promise, opts, toastOpts?) => {\r\n if (resolvedApi) return resolvedApi.promise(promise, opts, toastOpts);\r\n // For promises, it needs to wait for the API\r\n return apiReady.then((api) => api.promise(promise, opts, toastOpts));\r\n };\r\n\r\n toast.destroy = () => {\r\n if (root) {\r\n root.unmount();\r\n root = null;\r\n }\r\n container.remove();\r\n resolvedApi = null;\r\n };\r\n\r\n return toast;\r\n}\r\n"],"names":["ToasterContext","createContext","toasterReducer","state","action","t","CheckCircleIcon","props","jsxs","jsx","XCircleIcon","AlertTriangleIcon","InfoIcon","XIcon","SpinnerIcon","counter","generateId","cx","args","variantIcon","EXIT_DURATION","ToastItem","React","toast","onDismiss","onRemove","hasEntered","setHasEntered","useState","useEffect","raf","delay","timer","isPaused","setIsPaused","remainingRef","useRef","progress","setProgress","progressTransition","setProgressTransition","handleMouseEnter","useCallback","handleMouseLeave","Icon","ToastContainer","position","toasts","maxVisible","ctx","useContext","active","exiting","visible","queuedCount","ALL_POSITIONS","Toast23Provider","children","defaultPosition","defaultDuration","dispatch","useReducer","addToast","message","options","id","updateToast","updates","dismissToast","removeToast","contextValue","useMemo","groupedToasts","groups","pos","useToast","msg","opts","content","promiseOrFn","toastOpts","promise","result","error","_resolveApi","Bridge","api","createToast23","duration","container","root","createRoot","apiReady","resolve","queue","resolvedApi","call","proxyCall","method"],"mappings":"gcAeaA,EAAiBC,EAAAA,cAA0C,IAAI,EAMrE,SAASC,EACdC,EACAC,EACiB,CACjB,OAAQA,EAAO,KAAA,CACb,IAAK,MACH,MAAO,CAAC,GAAGD,EAAOC,EAAO,KAAK,EAEhC,IAAK,SAEH,OADeD,EAAM,KAAME,GAAMA,EAAE,KAAOD,EAAO,MAAM,EAAE,EAEhDD,EAAM,IAAKE,GAChBA,EAAE,KAAOD,EAAO,MAAM,GAClB,CACE,GAAGC,EACH,GAAGD,EAAO,MACV,QAASC,EAAE,QAAU,EACrB,UAAW,EAAA,EAEbA,CAAA,EAGD,CAAC,GAAGF,EAAOC,EAAO,KAAK,EAGhC,IAAK,SACH,OAAOD,EAAM,IAAK,GAChB,EAAE,KAAOC,EAAO,GACZ,CACE,GAAG,EACH,GAAGA,EAAO,QAEV,QAAS,EAAE,QAAU,EAErB,UAAW,EAAA,EAEb,CAAA,EAGR,IAAK,UAEH,OAAKA,EAAO,GAGLD,EAAM,IAAK,GAChB,EAAE,KAAOC,EAAO,GAAK,CAAE,GAAG,EAAG,UAAW,IAAS,CAAA,EAH1CD,EAAM,IAAK,IAAO,CAAE,GAAG,EAAG,UAAW,EAAA,EAAO,EAMvD,IAAK,SAEH,OAAKC,EAAO,GACLD,EAAM,OAAQ,GAAM,EAAE,KAAOC,EAAO,EAAE,EADtB,CAAA,EAGzB,QACE,OAAOD,CAAA,CAEb,CClEO,MAAMG,EAAkCC,GAC7CC,EAAAA,KAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,MAAM,SACN,OAAO,SACP,KAAK,OACJ,GAAGD,EAEJ,SAAA,CAAAE,EAAAA,IAAC,SAAA,CAAO,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,KAAK,cAAA,CAAe,EACnDA,EAAAA,IAAC,OAAA,CACC,EAAE,sBACF,OAAO,OACP,YAAa,EACb,cAAc,QACd,eAAe,QACf,KAAK,MAAA,CAAA,CACP,CAAA,CACF,EAIWC,EAA8BH,GACzCC,EAAAA,KAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,MAAM,SACN,OAAO,SACP,KAAK,OACJ,GAAGD,EAEJ,SAAA,CAAAE,EAAAA,IAAC,SAAA,CAAO,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,KAAK,cAAA,CAAe,EACnDA,EAAAA,IAAC,OAAA,CACC,GAAI,GACJ,GAAI,EACJ,GAAI,GACJ,GAAI,GACJ,OAAO,OACP,YAAa,EACb,cAAc,OAAA,CAAA,EAEhBA,EAAAA,IAAC,UAAO,GAAI,GAAI,GAAI,GAAI,EAAG,EAAG,KAAK,MAAA,CAAO,CAAA,CAAA,CAC5C,EAIWE,EAAoCJ,GAC/CC,EAAAA,KAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,MAAM,SACN,OAAO,SACP,KAAK,OACJ,GAAGD,EAEJ,SAAA,CAAAE,EAAAA,IAAC,OAAA,CACC,EAAE,2FACF,KAAK,cAAA,CAAA,EAEPA,EAAAA,IAAC,OAAA,CACC,GAAI,GACJ,GAAI,IACJ,GAAI,GACJ,GAAI,GACJ,OAAO,OACP,YAAa,EACb,cAAc,OAAA,CAAA,EAEhBA,EAAAA,IAAC,UAAO,GAAI,GAAI,GAAI,GAAI,EAAG,EAAG,KAAK,MAAA,CAAO,CAAA,CAAA,CAC5C,EAIWG,EAA2BL,GACtCC,EAAAA,KAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,MAAM,SACN,OAAO,SACP,KAAK,OACJ,GAAGD,EAEJ,SAAA,CAAAE,EAAAA,IAAC,SAAA,CAAO,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,KAAK,cAAA,CAAe,EACnDA,EAAAA,IAAC,OAAA,CACC,GAAI,GACJ,GAAI,GACJ,GAAI,GACJ,GAAI,GACJ,OAAO,OACP,YAAa,EACb,cAAc,OAAA,CAAA,EAEhBA,EAAAA,IAAC,UAAO,GAAI,GAAI,GAAI,EAAG,EAAG,EAAG,KAAK,MAAA,CAAO,CAAA,CAAA,CAC3C,EAIWI,EAAwBN,GACnCC,EAAAA,KAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAa,EACb,cAAc,QACd,eAAe,QACf,MAAM,UACN,OAAO,UACN,GAAGD,EAEJ,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,GAAI,GAAI,GAAI,EAAG,GAAI,EAAG,GAAI,EAAA,CAAI,EACpCA,EAAAA,IAAC,QAAK,GAAI,EAAG,GAAI,EAAG,GAAI,GAAI,GAAI,EAAA,CAAI,CAAA,CAAA,CACtC,EAIWK,EAA8BP,GACzCE,EAAAA,IAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAa,EACb,cAAc,QACd,eAAe,QACf,MAAM,SACN,OAAO,SACP,UAAU,kBACT,GAAGF,EAEJ,SAAAE,EAAAA,IAAC,OAAA,CAAK,EAAE,6BAAA,CAA8B,CAAA,CACxC,EC1IF,IAAIM,EAAU,EAMP,SAASC,GAAqB,CACnC,MAAO,OAAO,EAAED,CAAO,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,EACnE,CAKO,SAASE,KAAMC,EAAyD,CAC7E,OAAOA,EAAK,OAAO,OAAO,EAAE,KAAK,GAAG,CACtC,CCOA,MAAMC,EAAuE,CAC3E,QAASb,EACT,MAAOI,EACP,QAASC,EACT,KAAMC,EACN,QAASA,EACT,QAASE,CACX,EAYMM,EAAgB,IAGTC,EAAsCC,EAAM,KACvD,CAAC,CAAE,MAAAC,EAAO,UAAAC,EAAW,SAAAC,KAAe,CAElC,KAAM,CAACC,EAAYC,CAAa,EAAIC,EAAAA,SAAS,EAAK,EAGlDC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAM,sBAAsB,IAAMH,EAAc,EAAI,CAAC,EAC3D,MAAO,IAAM,qBAAqBG,CAAG,CACvC,EAAG,CAAA,CAAE,EAILD,EAAAA,UAAU,IAAM,CACd,GAAI,CAACN,EAAM,UAAW,OACtB,MAAMQ,EAAQR,EAAM,aAAeH,EAC7BY,EAAQ,WAAW,IAAMP,EAASF,EAAM,EAAE,EAAGQ,CAAK,EACxD,MAAO,IAAM,aAAaC,CAAK,CACjC,EAAG,CAACT,EAAM,UAAWA,EAAM,GAAIA,EAAM,YAAaE,CAAQ,CAAC,EAG3D,KAAM,CAACQ,EAAUC,CAAW,EAAIN,EAAAA,SAAS,EAAK,EACxCO,EAAeC,EAAAA,OAAOb,EAAM,QAAQ,EAKpC,CAACc,EAAUC,CAAW,EAAIV,EAAAA,SAAS,GAAG,EAEtC,CAACW,EAAoBC,CAAqB,EAAIZ,EAAAA,SAAS,MAAM,EAInEC,EAAAA,UAAU,IAAM,CACdM,EAAa,QAAUZ,EAAM,SAC7Be,EAAY,GAAG,EACfE,EAAsB,MAAM,CAC9B,EAAG,CAACjB,EAAM,QAASA,EAAM,QAAQ,CAAC,EAElCM,EAAAA,UAAU,IAAM,CAEd,GACEN,EAAM,UAAY,GAClBA,EAAM,UAAY,WAClB,CAACG,GACDH,EAAM,UAEN,OA4CJ,GAAIU,EAAU,CAEdO,EAAsB,sBAAsB,EAC5CF,EAAY,GAAG,EACf,MACF,CAGAA,EAAY,GAAG,EACf,sBAAsB,IAAM,CAC1BE,EAAsB,SAASjB,EAAM,QAAQ,WAAW,EACxDe,EAAY,CAAC,CACf,CAAC,EAED,MAAMN,EAAQ,WAAW,IAAM,CAC7BR,EAAUD,EAAM,EAAE,CACpB,EAAGA,EAAM,QAAQ,EAEjB,MAAO,IAAM,aAAaS,CAAK,CACjC,EAAG,CACDC,EACAV,EAAM,SACNA,EAAM,QACNA,EAAM,UACNA,EAAM,GACNG,EACAF,CAAA,CACD,EAGG,MAAMiB,EAAmBC,EAAAA,YAAY,IAAMR,EAAY,EAAI,EAAG,CAAA,CAAE,EAC1DS,EAAmBD,EAAAA,YAAY,IAAMR,EAAY,EAAK,EAAG,CAAA,CAAE,EAG3DU,EAAOzB,EAAYI,EAAM,OAAO,GAAKX,EAG3C,OAAIW,EAAM,SAENd,EAAAA,IAAC,MAAA,CACC,UAAWQ,EACT,oCACA,CAACS,GAAc,yBACfH,EAAM,WAAa,uBAAA,EAErB,KAAK,QACL,YAAU,SACV,cAAY,OACZ,aAAckB,EACd,aAAcE,EAEb,SAAApB,EAAM,OAAA,CAAA,EAMXf,EAAAA,KAAC,MAAA,CACC,UAAWS,EACT,eACA,iBAAiBM,EAAM,OAAO,GAC9B,CAACG,GAAc,yBACfH,EAAM,WAAa,uBAAA,EAErB,KAAK,QACL,YAAWA,EAAM,UAAY,QAAU,YAAc,SACrD,cAAY,OACZ,aAAckB,EACd,aAAcE,EAGd,SAAA,CAAAlC,EAAAA,IAAC,OAAA,CAAK,UAAWQ,EAAG,eAAgB,iBAAiBM,EAAM,OAAO,EAAE,EAClE,SAAAd,EAAAA,IAACmC,EAAA,CAAA,CAAK,EACR,EAGApC,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACZ,SAAA,CAAAe,EAAM,OAASd,EAAAA,IAAC,MAAA,CAAI,UAAU,gBAAiB,WAAM,MAAM,EAC5DA,EAAAA,IAAC,MAAA,CACC,UAAWQ,EACT,kBACAM,EAAM,OAAS,6BAAA,EAGhB,SAAAA,EAAM,OAAA,CAAA,CACT,EACF,EAGCA,EAAM,aACLd,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,UAAU,kBACV,QAAS,IAAMe,EAAUD,EAAM,EAAE,EACjC,aAAW,uBAEX,eAACV,EAAA,CAAA,CAAM,CAAA,CAAA,EAKVU,EAAM,SAAW,GAAKA,EAAM,UAAY,WACvCd,EAAAA,IAAC,MAAA,CACC,UAAWQ,EACT,mBACA,qBAAqBM,EAAM,OAAO,EAAA,EAEpC,MAAO,CACL,MAAO,GAAGc,CAAQ,IAClB,WAAYE,CAAA,CACd,CAAA,CACF,CAAA,CAAA,CAIR,CACF,EAEAlB,EAAU,YAAc,YC1OjB,MAAMwB,EAAgDvB,EAAM,KACjE,CAAC,CAAE,SAAAwB,EAAU,OAAAC,EAAQ,WAAAC,KAAsC,CACzD,MAAMC,EAAMC,EAAAA,WAAWlD,CAAc,EACrC,GAAI,CAACiD,EAAK,OAAO,KAGjB,MAAME,EAASJ,EAAO,OAAQ1C,GAAM,CAACA,EAAE,SAAS,EAC1C+C,EAAUL,EAAO,OAAQ1C,GAAMA,EAAE,SAAS,EAG1CgD,EAAU,CAAC,GAAGF,EAAO,MAAM,EAAGH,CAAU,EAAG,GAAGI,CAAO,EAE3D,GAAIC,EAAQ,SAAW,EAAG,OAAO,KAGjC,MAAMC,EAAc,KAAK,IAAI,EAAGH,EAAO,OAASH,CAAU,EAE1D,OACExC,EAAAA,KAAC,MAAA,CACC,UAAWS,EAAG,oBAAqB,sBAAsB6B,CAAQ,EAAE,EACnE,aAAW,gBACX,KAAK,SAEJ,SAAA,CAAAO,EAAQ,IAAK9B,GACZd,EAAAA,IAACY,EAAA,CAEC,MAAAE,EACA,UAAW0B,EAAI,aACf,SAAUA,EAAI,WAAA,EAHT1B,EAAM,EAAA,CAKd,EACA+B,EAAc,GACb9C,EAAAA,KAAC,OAAI,UAAU,sBAAsB,YAAU,SAAS,SAAA,CAAA,IACpD8C,EAAY,OAAA,CAAA,CAChB,CAAA,CAAA,CAAA,CAIR,CACF,EAEAT,EAAe,YAAc,iBCrC7B,MAAMU,EAAiC,CACrC,YACA,WACA,aACA,eACA,cACA,eACF,EAEaC,EAAkD,CAAC,CAC9D,SAAAC,EACA,WAAAT,EAAa,EACb,SAAUU,EAAkB,YAC5B,SAAUC,EAAkB,GAC9B,IAAM,CACJ,KAAM,CAACZ,EAAQa,CAAQ,EAAIC,EAAAA,WAAW3D,EAAgB,CAAA,CAAE,EAIlD4D,EAAWpB,EAAAA,YACf,CAACqB,EAA6BC,IAA2E,CACvG,MAAMC,EAAKD,GAAS,IAAMhD,EAAA,EACpBO,EAAuB,CAC3B,GAAA0C,EACA,QAAAF,EACA,MAAOC,GAAS,MAChB,QAASA,GAAS,SAAW,UAC7B,SAAUA,GAAS,UAAYL,EAC/B,SAAUK,GAAS,UAAYN,EAC/B,YAAaM,GAAS,aAAe,GACrC,YAAaA,GAAS,aAAe,IACrC,UAAW,GACX,UAAW,KAAK,IAAA,EAChB,QAAS,EACT,SAAUA,GAAS,QAAA,EAGrB,OAAIA,GAAS,GACXJ,EAAS,CAAE,KAAM,SAAU,MAAArC,CAAA,CAAO,EAElCqC,EAAS,CAAE,KAAM,MAAO,MAAArC,CAAA,CAAO,EAE1B0C,CACT,EACA,CAACN,EAAiBD,CAAe,CAAA,EAG7BQ,EAAcxB,EAAAA,YAClB,CACEuB,EACAE,IAMG,CACHP,EAAS,CAAE,KAAM,SAAU,GAAAK,EAAI,QAAAE,EAAS,CAC1C,EACA,CAAA,CAAC,EAGGC,EAAe1B,cAAauB,GAAgB,CAChDL,EAAS,CAAE,KAAM,UAAW,GAAAK,CAAA,CAAI,CAClC,EAAG,CAAA,CAAE,EAECI,EAAc3B,cAAauB,GAAgB,CAC/CL,EAAS,CAAE,KAAM,SAAU,GAAAK,CAAA,CAAI,CACjC,EAAG,CAAA,CAAE,EAICK,EAAoCC,EAAAA,QACxC,KAAO,CACL,SAAAT,EACA,YAAAI,EACA,aAAAE,EACA,YAAAC,EACA,OAAQ,CACN,WAAArB,EACA,SAAUU,EACV,SAAUC,CAAA,CACZ,GAEF,CACEG,EACAI,EACAE,EACAC,EACArB,EACAU,EACAC,CAAA,CACF,EAKIa,EAAgBD,EAAAA,QAAQ,IAAM,CAClC,MAAME,EAAiD,CACrD,YAAa,CAAA,EACb,WAAY,CAAA,EACZ,aAAc,CAAA,EACd,eAAgB,CAAA,EAChB,cAAe,CAAA,EACf,gBAAiB,CAAA,CAAC,EAEpB,UAAWpE,KAAK0C,EACd0B,EAAOpE,EAAE,QAAQ,EAAE,KAAKA,CAAC,EAE3B,OAAOoE,CACT,EAAG,CAAC1B,CAAM,CAAC,EAEX,OACEvC,EAAAA,KAACR,EAAe,SAAf,CAAwB,MAAOsE,EAC7B,SAAA,CAAAb,EAGAF,EAAc,IAAKmB,GAClBF,EAAcE,CAAG,EAAE,OAAS,EAC1BjE,EAAAA,IAACoC,EAAA,CAEC,SAAU6B,EACV,OAAQF,EAAcE,CAAG,EACzB,WAAA1B,CAAA,EAHK0B,CAAA,EAKL,IAAA,CACN,EACF,CAEJ,EAEAlB,EAAgB,YAAc,kBCvIvB,SAASmB,GAAqB,CACnC,MAAM1B,EAAMC,EAAAA,WAAWlD,CAAc,EAErC,GAAI,CAACiD,EACH,MAAM,IAAI,MACR,+HAAA,EAKJ,OAAOsB,EAAAA,QAAQ,IAAM,CAEnB,MAAMhD,GAAS,CAACwC,EAA6BC,IAC3Cf,EAAI,SAASc,EAASC,CAAO,GAG/B,OAAAzC,EAAM,QAAU,CAACqD,EAAKC,IACpB5B,EAAI,SAAS2B,EAAK,CAAE,GAAGC,EAAM,QAAS,SAAA,CAAW,EAEnDtD,EAAM,MAAQ,CAACqD,EAAKC,IAClB5B,EAAI,SAAS2B,EAAK,CAAE,GAAGC,EAAM,QAAS,OAAA,CAAS,EAEjDtD,EAAM,QAAU,CAACqD,EAAKC,IACpB5B,EAAI,SAAS2B,EAAK,CAAE,GAAGC,EAAM,QAAS,SAAA,CAAW,EAEnDtD,EAAM,KAAO,CAACqD,EAAKC,IAAS5B,EAAI,SAAS2B,EAAK,CAAE,GAAGC,EAAM,QAAS,MAAA,CAAQ,EAG1EtD,EAAM,QAAU,CAACqD,EAAKC,IACpB5B,EAAI,SAAS2B,EAAK,CAChB,GAAGC,EACH,QAAS,UACT,SAAUA,GAAM,UAAY,EAC5B,YAAaA,GAAM,aAAe,EAAA,CACnC,EAGHtD,EAAM,OAAS,CAACuD,EAASD,IACvB5B,EAAI,SAAS6B,EAAS,CAAE,GAAGD,EAAM,QAAS,UAAW,SAAU,GAAM,EAGvEtD,EAAM,QAAW0C,GAAgBhB,EAAI,aAAagB,CAAE,EAGpD1C,EAAM,OAAU0C,GAAgBhB,EAAI,YAAYgB,CAAE,EAGlD1C,EAAM,QAAU,MACdwD,EACAF,EACAG,IACe,CACf,MAAMf,EAAKhB,EAAI,SAAS4B,EAAK,QAAS,CACpC,GAAGG,EACH,QAAS,UACT,SAAU,EACV,YAAa,EAAA,CACE,EAEXC,EACJ,OAAOF,GAAgB,WAAaA,IAAgBA,EAEtD,GAAI,CACF,MAAMG,EAAS,MAAMD,EACfL,EACJ,OAAOC,EAAK,SAAY,WACpBA,EAAK,QAAQK,CAAM,EACnBL,EAAK,QACX,OAAA5B,EAAI,YAAYgB,EAAI,CAClB,QAASW,EACT,QAAS,UACT,SAAUI,GAAW,UAAY/B,EAAI,OAAO,SAC5C,YAAa,EAAA,CACd,EACMiC,CACT,OAASC,EAAO,CACd,MAAMP,EACJ,OAAOC,EAAK,OAAU,WAAaA,EAAK,MAAMM,CAAK,EAAIN,EAAK,MAC9D,MAAA5B,EAAI,YAAYgB,EAAI,CAClB,QAASW,EACT,QAAS,QACT,SAAUI,GAAW,UAAY/B,EAAI,OAAO,SAC5C,YAAa,EAAA,CACd,EACKkC,CACR,CACF,EAEO5D,CACT,EAAG,CACD0B,EAAI,SACJA,EAAI,YACJA,EAAI,aACJA,EAAI,YACJA,EAAI,OAAO,QAAA,CACZ,CACH,CCtCA,IAAImC,EAAgD,KAEpD,SAASC,GAAS,CAChB,MAAMC,EAAMX,EAAA,EAIZrD,OAAAA,EAAM,UAAU,IAAM,CAChB8D,IACFA,EAAYE,CAAG,EACfF,EAAc,KAElB,EAAG,CAACE,CAAG,CAAC,EAID,IACT,CAaO,SAASC,EACdvB,EAA6B,GACT,CACpB,KAAM,CAAE,SAAAlB,EAAW,YAAa,WAAAE,EAAa,EAAG,SAAAwC,EAAW,KAASxB,EAG9DyB,EAAY,SAAS,cAAc,KAAK,EAC9CA,EAAU,aAAa,0BAA2B,EAAE,EACpDA,EAAU,MAAM,QAAU,WAC1B,SAAS,KAAK,YAAYA,CAAS,EAInC,IAAIC,EAAoBC,EAAAA,WAAWF,CAAS,EAE5C,MAAMG,EAAW,IAAI,QAAmBC,GAAY,CAClDT,EAAcS,CAChB,CAAC,EAIKC,EAAsB,CAAA,EAC5B,IAAIC,EAA+B,KAGnCH,EAAS,KAAMN,GAAQ,CACrBS,EAAcT,EACd,UAAWU,KAAQF,EACbE,EAAK,SAAW,WACjBV,EAAY,GAAGU,EAAK,IAAI,EAExBV,EAAYU,EAAK,MAAM,EAAE,GAAGA,EAAK,IAAI,EAG1CF,EAAM,OAAS,CACjB,CAAC,EAGDJ,EAAK,OACHpE,EAAM,cACJkC,EACA,CAAE,SAAAV,EAAU,WAAAE,EAAY,SAAAwC,CAAA,EACxBlE,EAAM,cAAc+D,CAAM,CAAA,CAC5B,EAIF,MAAMY,EAAY,CAACC,KAAmBhF,IAChC6E,EACMA,EAAoBG,CAAM,EAAE,GAAGhF,CAAI,GAE7C4E,EAAM,KAAK,CAAE,OAAAI,EAAQ,KAAAhF,CAAA,CAAM,EACpB,UAGHK,GAAS,CAACwC,EAA6Bc,IACvCkB,EAAoBA,EAAYhC,EAASc,CAAI,GACjDiB,EAAM,KAAK,CAAE,OAAQ,WAAY,KAAM,CAAC/B,EAASc,CAAI,EAAG,EACjD,WAGT,OAAAtD,EAAM,QAAU,CAACqD,EAAKC,IAASoB,EAAU,UAAWrB,EAAKC,CAAI,EAC7DtD,EAAM,MAAQ,CAACqD,EAAKC,IAASoB,EAAU,QAASrB,EAAKC,CAAI,EACzDtD,EAAM,QAAU,CAACqD,EAAKC,IAASoB,EAAU,UAAWrB,EAAKC,CAAI,EAC7DtD,EAAM,KAAO,CAACqD,EAAKC,IAASoB,EAAU,OAAQrB,EAAKC,CAAI,EACvDtD,EAAM,QAAU,CAACqD,EAAKC,IAASoB,EAAU,UAAWrB,EAAKC,CAAI,EAC7DtD,EAAM,OAAS,CAACuD,EAASD,IAASoB,EAAU,SAAUnB,EAASD,CAAI,EACnEtD,EAAM,QAAW0C,GAAQgC,EAAU,UAAWhC,CAAE,EAChD1C,EAAM,OAAU0C,GAAQgC,EAAU,SAAUhC,CAAE,EAE9C1C,EAAM,QAAU,CAAC0D,EAASJ,EAAMG,IAC1Be,EAAoBA,EAAY,QAAQd,EAASJ,EAAMG,CAAS,EAE7DY,EAAS,KAAMN,GAAQA,EAAI,QAAQL,EAASJ,EAAMG,CAAS,CAAC,EAGrEzD,EAAM,QAAU,IAAM,CAChBmE,IACFA,EAAK,QAAA,EACLA,EAAO,MAETD,EAAU,OAAA,EACVM,EAAc,IAChB,EAEOxE,CACT"}
package/dist/index.d.ts CHANGED
@@ -1,119 +1,6 @@
1
- import { ReactNode } from 'react';
2
-
3
- /**
4
- * Create a standalone toast API that works outside of React.
5
- *
6
- * Internally mounts a tiny React tree (provider + bridge) into a hidden
7
- * container. Returns a callable toast object with `.success()`, `.error()`, etc.
8
- *
9
- * Call `.destroy()` when your application unmounts to clean up.
10
- */
11
- export declare function createToast23(options?: StandaloneOptions): StandaloneToastApi;
12
-
13
- /** Options for `toast.promise()`. */
14
- export declare interface PromiseOptions<T> {
15
- /** Message shown while the promise is pending. */
16
- loading: string;
17
- /** Message on fulfillment. Can be a function receiving the resolved value. */
18
- success: string | ((data: T) => string);
19
- /** Message on rejection. Can be a function receiving the error. */
20
- error: string | ((err: unknown) => string);
21
- }
22
-
23
- export declare interface StandaloneOptions {
24
- /** Where on screen toasts appear. @default "top-right" */
25
- position?: ToastPosition;
26
- /** Max simultaneous toasts. @default 5 */
27
- maxVisible?: number;
28
- /** Default auto-dismiss duration in ms. @default 5000 */
29
- duration?: number;
30
- }
31
-
32
- export declare interface StandaloneToastApi {
33
- /** Show a default toast. Returns the toast id. */
34
- (message: string | ReactNode, options?: ToastOptions): string;
35
- /** Show a success toast. */
36
- success: (message: string, options?: Omit<ToastOptions, "variant">) => string;
37
- /** Show an error toast. */
38
- error: (message: string, options?: Omit<ToastOptions, "variant">) => string;
39
- /** Show a warning toast. */
40
- warning: (message: string, options?: Omit<ToastOptions, "variant">) => string;
41
- /** Show an info toast. */
42
- info: (message: string, options?: Omit<ToastOptions, "variant">) => string;
43
- /** Show a loading toast. Returns the toast id for later update. */
44
- loading: (message: string, options?: Omit<ToastOptions, "variant">) => string;
45
- /** Show a custom toast with JSX content and no default styles. */
46
- custom: (content: ReactNode, options?: Omit<ToastOptions, "variant">) => string;
47
- /** Track an async operation with loading → success / error transitions. */
48
- promise: <T>(promise: Promise<T> | (() => Promise<T>), options: PromiseOptions<T>, toastOptions?: ToastOptions) => Promise<T>;
49
- /** Manually dismiss a toast by id. Omit id to dismiss all. */
50
- dismiss: (id?: string) => void;
51
- /** Instantly remove a toast from DOM (no exit animation). Omit id to remove all. */
52
- remove: (id?: string) => void;
53
- /** Unmount the React root and remove the container from the DOM. */
54
- destroy: () => void;
55
- }
56
-
57
- export declare const Toast23Provider: React.FC<Toast23ProviderProps>;
58
-
59
- /** Props for `<Toast23Provider>`. */
60
- export declare interface Toast23ProviderProps {
61
- children: ReactNode;
62
- /** Maximum number of simultaneously visible toasts. @default 5 */
63
- maxVisible?: number;
64
- /** Default position on screen. @default "top-right" */
65
- position?: ToastPosition;
66
- /** Default auto-dismiss duration in ms. @default 5000 */
67
- duration?: number;
68
- }
69
-
70
- /**
71
- * The callable toast API returned by `useToast()`.
72
- *
73
- * Can be invoked directly — `toast("hi")` — or via variant helpers.
74
- */
75
- export declare interface ToastApi {
76
- (message: string | ReactNode, options?: ToastOptions): string;
77
- success: (message: string, options?: Omit<ToastOptions, "variant">) => string;
78
- error: (message: string, options?: Omit<ToastOptions, "variant">) => string;
79
- warning: (message: string, options?: Omit<ToastOptions, "variant">) => string;
80
- info: (message: string, options?: Omit<ToastOptions, "variant">) => string;
81
- /** Show a loading toast. Returns the toast id for later update. */
82
- loading: (message: string, options?: Omit<ToastOptions, "variant">) => string;
83
- /** Show a custom toast with JSX content and no default styles. */
84
- custom: (content: ReactNode, options?: Omit<ToastOptions, "variant">) => string;
85
- /** Track an async operation with loading → success / error transitions. */
86
- promise: <T>(promise: Promise<T> | (() => Promise<T>), options: PromiseOptions<T>, toastOptions?: ToastOptions) => Promise<T>;
87
- /** Manually dismiss a toast by id. Omit id to dismiss all. */
88
- dismiss: (id?: string) => void;
89
- /** Instantly remove a toast from DOM (no exit animation). Omit id to remove all. */
90
- remove: (id?: string) => void;
91
- }
92
-
93
- /** Options accepted when creating a toast. */
94
- export declare interface ToastOptions {
95
- /** Provide a fixed id to update an existing toast or prevent duplicates. */
96
- id?: string;
97
- /** Optional heading displayed above the message. */
98
- title?: string;
99
- /** Visual variant. Defaults to `"default"`. */
100
- variant?: ToastVariant;
101
- /** Auto-dismiss duration in ms. `0` = persistent. Defaults to provider value. */
102
- duration?: number;
103
- /** Screen position override. Defaults to provider value. */
104
- position?: ToastPosition;
105
- /** Whether the user can manually dismiss the toast. Defaults to `true`. */
106
- dismissible?: boolean;
107
- /** Delay in ms before removing from DOM after dismiss (for exit animation). @default 1000 */
108
- removeDelay?: number;
109
- }
110
-
111
- /** Screen position where toasts are rendered. */
112
- export declare type ToastPosition = "top-right" | "top-left" | "top-center" | "bottom-right" | "bottom-left" | "bottom-center";
113
-
114
- /** Visual variant of a toast notification. */
115
- export declare type ToastVariant = "success" | "error" | "warning" | "info" | "default";
116
-
117
- export declare function useToast(): ToastApi;
118
-
119
- export { }
1
+ export { Toast23Provider } from './provider';
2
+ export { useToast } from './use-toast';
3
+ export { createToast23 } from './standalone';
4
+ export type { ToastVariant, ToastPosition, ToastOptions, ToastApi, Toast23ProviderProps, PromiseOptions, } from './types';
5
+ export type { StandaloneOptions, StandaloneToastApi } from './standalone';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,YAAY,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,oBAAoB,EACpB,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}