robot-toast 2.1.5 → 2.1.6
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.
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/styles-injector.ts","../src/toast.ts","../src/utils.ts","../src/types.ts","../src/index.ts"],"names":["_InjectStyles","styleId","styles","styleElement","InjectStyles","styles_injector_default","_nextId","nextId","STACK_GAP","chunkButtons","buttons","n","rows","i","ToastItem","id","options","onRemove","resolved","positionIsLeft","initialSide","fn","bottomPx","w","classes","assertive","v","ALLOWED_EXTS","ext","r","kind","img","box","key","value","camelCaseKey","g","closeBtn","e","body","text","footer","rowBtns","row","btn","pContainer","pBar","button","el","camelKey","err","rtl","robotHidden","messageHidden","showMessage","msgEnterClass","onMsgEntered","side","transitionSuffix","enterClass","onRobotEntered","done","afterMsg","exitClass","afterRobot","message","typeSpeed","index","active","tick","elapsed","onEnter","onLeave","onBlur","onFocus","onPointerDown","rect","onPointerMove","maxX","maxY","newLeft","newTop","onPointerUp","_e","currentTop","midX","centerX","snapToLeft","newRobotSide","finalLeft","finalTop","robotOnLeft","snapClass","_RobotToastManager","limit","toast","t","q","doneId","next","groups","pos","list","offset","RobotToastManager","ensureRobotToastReady","timeout","resolve","reject","startTime","interval","showRobotToast","closeAllRobotToasts","getRobotToastInstance","TOAST_POSITIONS","TOAST_TYPES","TOAST_THEMES","TOAST_TRANSITIONS","normalise","input","promise","messages","loadingOpts","loadingId","resolveOptions","fallbackType","base","registerGlobal","api"],"mappings":"aAKA,IAAMA,CAAAA,CAAN,MAAMA,CAAa,CAGjB,WAAA,EAAc,CACR,OAAO,QAAA,CAAa,GAAA,EAAeA,CAAAA,CAAa,QAAA,GAIpDA,CAAAA,CAAa,SAAW,IAAA,CACxB,IAAA,CAAK,SAAA,EAAU,EACjB,CAEQ,SAAA,EAAkB,CACxB,IAAMC,CAAAA,CAAU,oBAAA,CAGhB,GAAI,QAAA,CAAS,cAAA,CAAeA,CAAO,CAAA,CACjC,OAGF,IAAMC,CAAAA,CAAS;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CAgvBTC,CAAAA,CAAe,QAAA,CAAS,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","file":"index.js","sourcesContent":["/**\r\n * Style injection for RobotToast\r\n * Injects all required CSS into the document when instantiated\r\n */\r\n\r\nclass InjectStyles {\r\n private static injected = false;\r\n\r\n constructor() {\r\n if (typeof document === 'undefined' || InjectStyles.injected) {\r\n return;\r\n }\r\n\r\n InjectStyles.injected = true;\r\n this.injectCSS();\r\n }\r\n\r\n private injectCSS(): void {\r\n const styleId = 'robot-toast-styles';\r\n\r\n // Check if styles already exist\r\n if (document.getElementById(styleId)) {\r\n return;\r\n }\r\n\r\n const styles = `\r\n/* RobotToast v2 - CSS Styles */\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* WRAPPER - Fixed positioning container for each toast */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-wrapper {\r\n position: fixed;\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n opacity: 0;\r\n z-index: 99999;\r\n pointer-events: auto;\r\n touch-action: none;\r\n -webkit-user-select: none;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-visible {\r\n opacity: 1;\r\n}\r\n\r\n/* Position presets */\r\n.robot-toast-wrapper.robot-toast-top-right {\r\n top: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-left {\r\n top: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-center {\r\n top: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-right {\r\n bottom: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-left {\r\n bottom: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-center {\r\n bottom: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-rtl {\r\n direction: rtl;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-dragging .robot-toast-message {\r\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ROBOT - The animated character */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-robot {\r\n width: 65px;\r\n height: 70px;\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0;\r\n}\r\n\r\n.robot-toast-robot img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-left {\r\n animation: robot-enter-left 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right {\r\n animation: robot-enter-right 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left {\r\n animation: robot-exit-left 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right {\r\n animation: robot-exit-right 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-idle {\r\n opacity: 1;\r\n animation: robot-idle 2s ease-in-out infinite;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-left {\r\n animation: robot-snap-left 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-right {\r\n animation: robot-snap-right 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* MESSAGE BOX - Toast content container */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-message {\r\n position: relative;\r\n width: fit-content;\r\n min-width: 120px;\r\n max-width: min(400px, calc(100vw - 120px));\r\n /*\r\n * IMPORTANT: no padding on the outer box. Each section (.robot-toast-body,\r\n * .robot-toast-footer, .robot-toast-progress-container) owns its own\r\n * spacing, so optional sections can disappear without us having to tweak\r\n * margins / paddings anywhere else.\r\n */\r\n padding: 0;\r\n border-radius: 8px;\r\n margin: 0;\r\n opacity: 0;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\r\n user-select: none;\r\n cursor: default;\r\n box-sizing: border-box;\r\n}\r\n\r\n.robot-toast-message.robot-toast-empty {\r\n display: none;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light {\r\n background: #ffffff;\r\n color: #333333;\r\n border: 1px solid #e0e0e0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark {\r\n background: #2d2d2d;\r\n color: #f0f0f0;\r\n border: 1px solid #444444;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored {\r\n color: #ffffff;\r\n}\r\n\r\n/* Type-specific colors for colored theme */\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-default {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-info {\r\n background: linear-gradient(135deg, #2193b0 0%, #6dd5ed 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-success {\r\n background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-warning {\r\n background: linear-gradient(135deg, #fb6e3b 0%, #f5a623 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-error {\r\n background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);\r\n}\r\n\r\n/* Light theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-info {\r\n border-left: 4px solid #2193b0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-success {\r\n border-left: 4px solid #11998e;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-warning {\r\n border-left: 4px solid #fb6e3b;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-error {\r\n border-left: 4px solid #eb3349;\r\n}\r\n\r\n/* Dark theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-info {\r\n border-left: 4px solid #6dd5ed;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-success {\r\n border-left: 4px solid #38ef7d;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-warning {\r\n border-left: 4px solid #f5a623;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-error {\r\n border-left: 4px solid #f45c43;\r\n}\r\n\r\n.robot-toast-message.message-enter {\r\n animation: message-enter 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-message.message-exit {\r\n animation: message-exit 0.3s ease-in forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* CLOSE BUTTON */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-close {\r\n position: absolute;\r\n top: 4px;\r\n right: 4px;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n opacity: 0.6;\r\n transition: opacity 0.2s;\r\n padding: 0;\r\n width: 28px;\r\n height: 28px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: currentColor;\r\n}\r\n\r\n.robot-toast-close:hover {\r\n opacity: 1;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* DRAG HINT */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-drag-hint {\r\n position: absolute;\r\n left: 8px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 3px;\r\n opacity: 0.4;\r\n}\r\n\r\n.robot-toast-drag-hint span {\r\n display: block;\r\n width: 4px;\r\n height: 4px;\r\n border-radius: 50%;\r\n background: currentColor;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* BODY — the message zone. Always present, always owns its own padding. */\r\n/* Right padding leaves clear room for the absolute close button. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-body {\r\n padding: 10px 40px 10px 14px;\r\n}\r\n\r\n.robot-toast-text {\r\n font-size: 14px;\r\n line-height: 1.5;\r\n word-break: break-word;\r\n white-space: pre-wrap;\r\n font-weight: 500;\r\n min-width: 0;\r\n min-height: 1.5em;\r\n /* No padding-bottom here — body's padding-bottom handles spacing toward\r\n whichever section follows (footer, progress bar, or nothing). */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* FOOTER — the button zone. Rendered only when buttons.length > 0. */\r\n/* Owns its own bottom padding so there are no conditional margins anywhere. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-footer {\r\n /*\r\n * Symmetric vertical padding (10px top + 10px bottom) — matches body so\r\n * the two sections feel like equally-weighted \"cards\" stacked inside the\r\n * toast. This is intentional even though it doubles the gap between text\r\n * and buttons (10 body-bottom + 10 footer-top = 20px); the visual balance\r\n * matters more than the gap-tightness.\r\n */\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n}\r\n\r\n/* A row inside the footer. data-count drives width distribution — pure CSS,\r\n * no JS-side layout code. */\r\n.robot-toast-row {\r\n display: flex;\r\n gap: 6px;\r\n align-items: center;\r\n}\r\n\r\n/* 1 button in its row → content-sized, left-aligned (flex default) */\r\n.robot-toast-row[data-count=\"1\"] .robot-toast-btn {\r\n /* nothing — intrinsic width, flex-start alignment */\r\n}\r\n\r\n/* 2 or 3 buttons in a row → equal shares, filling the row's width */\r\n.robot-toast-row[data-count=\"2\"] .robot-toast-btn,\r\n.robot-toast-row[data-count=\"3\"] .robot-toast-btn {\r\n flex: 1;\r\n min-width: 0; /* let long labels shrink without breaking the 50/50 split */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* INLINE BUTTONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-btn {\r\n appearance: none;\r\n font: inherit;\r\n font-size: 12px;\r\n font-weight: 500;\r\n line-height: 1;\r\n padding: 6px 12px;\r\n border-radius: 5px;\r\n cursor: pointer;\r\n transition: background 0.15s ease, color 0.15s ease, transform 0.05s ease;\r\n white-space: nowrap;\r\n background: transparent;\r\n color: #52525b;\r\n border: 1px solid #e4e4e7;\r\n}\r\n.robot-toast-btn:hover { background: #f4f4f5; color: #18181b; }\r\n.robot-toast-btn:active { transform: scale(0.97); }\r\n\r\n/*\r\n * Solo CTA: when the toast has exactly one button, it's implicitly the\r\n * primary action. Render it filled/dark so it feels decisive (Undo / Retry\r\n * UX). A multi-button toast drops back to all-neutral — the caller picks a\r\n * primary via its own className.\r\n *\r\n * \"Exactly one button total\" = the single row has data-count=\"1\" AND is the\r\n * only row in the footer (covers the n=1 case; n=4 also has data-count rows\r\n * but they're paired, not only-child).\r\n */\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #18181b;\r\n color: #fafafa;\r\n border-color: #18181b;\r\n font-weight: 600;\r\n}\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #000;\r\n border-color: #000;\r\n color: #fafafa;\r\n}\r\n\r\n/* Dark theme — inverted neutral */\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn {\r\n color: #a1a1aa;\r\n border-color: #3f3f46;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn:hover {\r\n background: #27272a;\r\n color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #fafafa;\r\n color: #18181b;\r\n border-color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #e4e4e7;\r\n border-color: #e4e4e7;\r\n color: #18181b;\r\n}\r\n\r\n/* Colored theme — translucent whites keep contrast on any gradient */\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn {\r\n color: rgba(255, 255, 255, 0.9);\r\n border-color: rgba(255, 255, 255, 0.35);\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn:hover {\r\n background: rgba(255, 255, 255, 0.15);\r\n color: #fff;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: rgba(255, 255, 255, 0.95);\r\n color: #18181b;\r\n border-color: transparent;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #fff;\r\n color: #18181b;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* PROGRESS BAR */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-progress-container {\r\n width: 100%;\r\n height: 3px;\r\n background: rgba(0, 0, 0, 0.1);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-progress-container {\r\n background: rgba(255, 255, 255, 0.15);\r\n}\r\n\r\n.robot-toast-progress-bar {\r\n height: 100%;\r\n background: currentColor;\r\n transform-origin: left;\r\n transform: scaleX(1); /* ← starts full */\r\n}\r\n\r\n.robot-toast-theme-light.robot-toast-type-success .robot-toast-progress-bar { background: #11998e; }\r\n.robot-toast-theme-light.robot-toast-type-error .robot-toast-progress-bar { background: #eb3349; }\r\n.robot-toast-theme-light.robot-toast-type-warning .robot-toast-progress-bar { background: #fb6e3b; }\r\n.robot-toast-theme-light.robot-toast-type-info .robot-toast-progress-bar { background: #2193b0; }\r\n\r\n/* Dark theme progress bar colors */\r\n.robot-toast-theme-dark.robot-toast-type-success .robot-toast-progress-bar { background: #38ef7d; }\r\n.robot-toast-theme-dark.robot-toast-type-error .robot-toast-progress-bar { background: #f45c43; }\r\n.robot-toast-theme-dark.robot-toast-type-warning .robot-toast-progress-bar { background: #f5a623; }\r\n.robot-toast-theme-dark.robot-toast-type-info .robot-toast-progress-bar { background: #6dd5ed; }\r\n\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-auto {\r\n animation: robot-progress-countdown linear forwards;\r\n opacity: 0.8;\r\n}\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-paused {\r\n animation-play-state: paused !important;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ANIMATIONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n@keyframes robot-enter-left {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-enter-right {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-left {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n@keyframes robot-exit-right {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n\r\n@keyframes robot-idle {\r\n 0%, 100% {\r\n transform: translateY(0);\r\n }\r\n 50% {\r\n transform: translateY(-4px);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-left {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-right {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes message-enter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n@keyframes message-exit {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n}\r\n\r\n@keyframes robot-progress-countdown {\r\n from { transform: scaleX(1); }\r\n to { transform: scaleX(0); }\r\n}\r\n\r\n/* Slide transition animations */\r\n.robot-toast-robot.robot-enter-left-slide {\r\n animation: robot-enter-left-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-slide {\r\n animation: robot-enter-right-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-slide {\r\n animation: robot-exit-left-slide 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-slide {\r\n animation: robot-exit-right-slide 0.4s ease-in forwards;\r\n}\r\n\r\n/* Zoom transition animations */\r\n.robot-toast-robot.robot-enter-left-zoom,\r\n.robot-toast-robot.robot-enter-right-zoom {\r\n animation: robot-enter-zoom 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-zoom,\r\n.robot-toast-robot.robot-exit-right-zoom {\r\n animation: robot-exit-zoom 0.4s ease-in forwards;\r\n}\r\n\r\n/* Flip transition animations */\r\n.robot-toast-robot.robot-enter-left-flip {\r\n animation: robot-enter-left-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-flip {\r\n animation: robot-enter-right-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-flip {\r\n animation: robot-exit-left-flip 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-flip {\r\n animation: robot-exit-right-flip 0.4s ease-in forwards;\r\n}\r\n\r\n@keyframes robot-enter-left-slide {\r\n from { opacity: 0; transform: translateX(-60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-enter-right-slide {\r\n from { opacity: 0; transform: translateX(60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-exit-left-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(-60px); }\r\n}\r\n\r\n@keyframes robot-exit-right-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(60px); }\r\n}\r\n\r\n@keyframes robot-enter-zoom {\r\n from { opacity: 0; transform: scale(0.2); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-zoom {\r\n from { opacity: 1; transform: scale(1); }\r\n to { opacity: 0; transform: scale(0.2); }\r\n}\r\n\r\n@keyframes robot-enter-left-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-enter-right-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-exit-left-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n}\r\n\r\n@keyframes robot-exit-right-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n}\r\n\r\n/* message-enter variants */\r\n.robot-toast-message.message-enter-slide {\r\n animation: message-enter-slide 0.35s ease-out forwards;\r\n}\r\n.robot-toast-message.message-enter-zoom {\r\n animation: message-enter-zoom 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n.robot-toast-message.message-enter-flip {\r\n animation: message-enter-flip 0.4s ease-out forwards;\r\n}\r\n\r\n@keyframes message-enter-slide {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n@keyframes message-enter-zoom {\r\n from { opacity: 0; transform: scale(0.5); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n@keyframes message-enter-flip {\r\n from { opacity: 0; transform: perspective(400px) rotateX(-20deg); }\r\n to { opacity: 1; transform: perspective(400px) rotateX(0deg); }\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* RESPONSIVE - Mobile / small-screen tweaks */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n/*\r\n * Small-viewport tweaks. No !important / edge-to-edge override here — the\r\n * wrapper keeps its configured position preset and the message box stays\r\n * content-sized (just capped by max-width so it doesn't overflow). Drag\r\n * still works everywhere because no stylesheet rule competes with the\r\n * inline position the drag handler writes.\r\n */\r\n@media (max-width: 600px) {\r\n .robot-toast-wrapper {\r\n gap: 8px;\r\n max-width: calc(100vw - 24px);\r\n }\r\n\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-bottom-right { right: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-bottom-left { left: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-top-center { top: 12px; }\r\n .robot-toast-wrapper.robot-toast-bottom-right,\r\n .robot-toast-wrapper.robot-toast-bottom-left,\r\n .robot-toast-wrapper.robot-toast-bottom-center { bottom: 12px; }\r\n\r\n .robot-toast-wrapper.robot-toast-top-center,\r\n .robot-toast-wrapper.robot-toast-bottom-center {\r\n width: calc(100vw - 24px);\r\n justify-content: center;\r\n }\r\n\r\n .robot-toast-robot {\r\n width: 48px;\r\n height: 52px;\r\n }\r\n\r\n .robot-toast-message {\r\n min-width: 100px;\r\n max-width: calc(100vw - 48px - 24px - 8px);\r\n font-size: 13px;\r\n /* padding stays 0 on the outer box; sections own their spacing */\r\n }\r\n\r\n .robot-toast-body {\r\n padding: 10px 36px 10px 12px;\r\n }\r\n\r\n .robot-toast-footer {\r\n /* Same symmetric vertical padding as body — equal section weight on mobile too */\r\n padding: 10px;\r\n }\r\n\r\n .robot-toast-text {\r\n font-size: 13px;\r\n }\r\n\r\n .robot-toast-close {\r\n width: 24px;\r\n height: 24px;\r\n font-size: 20px;\r\n }\r\n}\r\n\r\n@media (max-width: 360px) {\r\n .robot-toast-robot {\r\n width: 40px;\r\n height: 44px;\r\n }\r\n .robot-toast-message {\r\n max-width: calc(100vw - 40px - 20px - 8px);\r\n }\r\n}\r\n `;\r\n\r\n const styleElement = document.createElement('style');\r\n styleElement.id = styleId;\r\n styleElement.textContent = styles;\r\n document.head.appendChild(styleElement);\r\n }\r\n}\r\n\r\nexport default InjectStyles;\r\n","/**\r\n * RobotToast v2\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * • Multi-toast support with configurable limit + queue\r\n * • Each toast is a self-contained ToastItem instance – no shared mutable state\r\n * • Sequenced robot enter → message pop-in, message pop-out → robot exit\r\n * • Full XY drag with viewport clamping; on drop the robot snaps to the\r\n * nearest screen edge (left / right) with a personality animation\r\n * • Progress bar auto-animates for the countdown; pauses correctly on hover\r\n * and drag; resumes with exact remaining time\r\n * • All event listeners are tracked and fully removed on close\r\n * • SVG-only enforcement for custom robot images; always renders at fixed size\r\n * • SSR-safe (all DOM access is guarded by typeof window / document checks)\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n */\r\n\r\nimport type { RobotToastOptions, ToastQueueItem, ToastButton } from './types';\r\nimport InjectStyles from './styles-injector';\r\n\r\n// ─── Unique ID counter ────────────────────────────────────────────────────────\r\nlet _nextId = 1;\r\nfunction nextId(): number { return _nextId++; }\r\n\r\n// ─── Vertical offset step between stacked toasts (px) ────────────────────────\r\nconst STACK_GAP = 16;\r\n\r\n/**\r\n * Split N buttons into rows according to the layout spec:\r\n * 1→[1] 2→[2] 3→[3] 4→[2,2]\r\n * 5→[3,2] 6→[3,3] 7→[3,2,2] 8→[3,3,2] 9→[3,3,3]\r\n * 10→[3,3,2,2] 11→[3,3,3,2] 12→[3,3,3,3] …\r\n * Rule: fill rows of 3 from the top. If the tail would leave a single\r\n * lonely button, steal one from the previous row so the last two rows\r\n * balance as [2, 2].\r\n */\r\nfunction chunkButtons<T>(buttons: T[]): T[][] {\r\n const n = buttons.length;\r\n if (n === 0) return [];\r\n if (n <= 3) return [buttons.slice()];\r\n if (n === 4) return [buttons.slice(0, 2), buttons.slice(2)];\r\n\r\n const rows: T[][] = [];\r\n let i = 0;\r\n while (n - i > 4) {\r\n rows.push(buttons.slice(i, i + 3));\r\n i += 3;\r\n }\r\n const rem = n - i;\r\n if (rem === 4) {\r\n rows.push(buttons.slice(i, i + 2));\r\n rows.push(buttons.slice(i + 2));\r\n } else {\r\n rows.push(buttons.slice(i));\r\n }\r\n return rows;\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n ToastItem – one live toast on screen\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass ToastItem {\r\n readonly id: number;\r\n private options: {\r\n message: string;\r\n autoClose: boolean | number;\r\n position: NonNullable<RobotToastOptions['position']>;\r\n type: NonNullable<RobotToastOptions['type']>;\r\n theme: NonNullable<RobotToastOptions['theme']>;\r\n style?: Record<string, string | number>;\r\n typeSpeed: number;\r\n robotVariant: string;\r\n hideProgressBar: boolean;\r\n pauseOnFocusLoss: boolean;\r\n draggable: boolean;\r\n nearScreen: boolean;\r\n pauseOnHover: boolean;\r\n rtl: boolean;\r\n transition: NonNullable<RobotToastOptions['transition']>;\r\n buttons?: ToastButton[];\r\n onOpen?: () => void;\r\n onClose?: () => void;\r\n };\r\n\r\n // DOM refs\r\n private wrapper: HTMLDivElement;\r\n private robotEl: HTMLDivElement;\r\n private messageBox: HTMLDivElement;\r\n private progressBar: HTMLDivElement | null = null;\r\n private messageText: HTMLDivElement;\r\n\r\n // Timer state\r\n private autoCloseDuration: number; // ms; 0 = no auto-close\r\n private remainingTime: number; // ms left on the countdown\r\n private timerStart: number | null = null; // when the current timer was set\r\n private closeTimeout: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // Interaction state\r\n private isDragging = false;\r\n private dragOffsetX = 0;\r\n private dragOffsetY = 0;\r\n private dragWidth = 0;\r\n private dragHeight = 0;\r\n private currentRobotSide: 'left' | 'right';\r\n private isHovered = false;\r\n private isFocusLost = false;\r\n private isClosed = false;\r\n\r\n // Cleanup\r\n private cleanupFns: Array<() => void> = [];\r\n\r\n // Callback to notify the manager when this toast dies\r\n private onRemove: (id: number) => void;\r\n\r\n constructor(id: number, options: RobotToastOptions, onRemove: (id: number) => void) {\r\n this.id = id;\r\n this.onRemove = onRemove;\r\n\r\n // ── Resolve all options with defaults ──────────────────────────────────\r\n const resolved = {\r\n message: options.message,\r\n autoClose: options.autoClose ?? 5000,\r\n position: options.position ?? 'bottom-right',\r\n type: options.type ?? 'default',\r\n theme: options.theme ?? 'light',\r\n style: options.style,\r\n typeSpeed: options.typeSpeed ?? 30,\r\n robotVariant: options.robotVariant ?? '',\r\n hideProgressBar: options.hideProgressBar ?? false,\r\n pauseOnFocusLoss: options.pauseOnFocusLoss ?? true,\r\n draggable: options.draggable ?? true,\r\n nearScreen: options.nearScreen ?? true,\r\n pauseOnHover: options.pauseOnHover ?? true,\r\n rtl: options.rtl ?? false,\r\n transition: options.transition ?? 'bounce',\r\n buttons: options.buttons,\r\n onOpen: options.onOpen,\r\n onClose: options.onClose,\r\n };\r\n\r\n this.options = resolved;\r\n \r\n // Determine initial robot side based on nearScreen\r\n // nearScreen: true → robot near screen edge (position's side)\r\n // nearScreen: false → robot away from screen edge (opposite side)\r\n const positionIsLeft = resolved.position.includes('left');\r\n \r\n let initialSide: 'left' | 'right';\r\n if (resolved.nearScreen) {\r\n // Robot near edge: follow position\r\n initialSide = positionIsLeft ? 'left' : 'right';\r\n } else {\r\n // Robot away from edge: opposite of position\r\n initialSide = positionIsLeft ? 'right' : 'left';\r\n }\r\n this.currentRobotSide = initialSide;\r\n this.autoCloseDuration = typeof resolved.autoClose === 'number'\r\n ? resolved.autoClose\r\n : (resolved.autoClose ? 5000 : 0);\r\n this.remainingTime = this.autoCloseDuration;\r\n\r\n // ── Build DOM ──────────────────────────────────────────────────────────\r\n this.wrapper = this.buildWrapper();\r\n this.robotEl = this.buildRobot();\r\n this.messageBox = this.buildMessageBox();\r\n this.messageText = this.messageBox.querySelector('.robot-toast-text')!;\r\n this.progressBar = this.messageBox.querySelector('.robot-toast-progress-bar');\r\n\r\n // Empty message → hide message box entirely (only the robot shows)\r\n if (resolved.message === '') {\r\n this.messageBox.classList.add('robot-toast-empty');\r\n }\r\n\r\n this.assembleLayout();\r\n document.body.appendChild(this.wrapper);\r\n\r\n // ── Wire interactions ──────────────────────────────────────────────────\r\n if (resolved.draggable) this.initDrag();\r\n if (resolved.pauseOnFocusLoss) this.initFocusWatcher();\r\n if (resolved.pauseOnHover) this.initHoverWatcher();\r\n\r\n // ── Kick off the entrance sequence ─────────────────────────────────────\r\n requestAnimationFrame(() => this.playEntrance());\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n close(): void {\r\n if (this.isClosed) return;\r\n this.isClosed = true;\r\n\r\n this.cancelTimer();\r\n this.cleanupFns.forEach(fn => fn());\r\n this.cleanupFns = [];\r\n\r\n this.playExit(() => {\r\n if (this.wrapper.parentNode) {\r\n this.wrapper.parentNode.removeChild(this.wrapper);\r\n }\r\n this.options.onClose?.();\r\n this.onRemove(this.id);\r\n });\r\n }\r\n\r\n /** Shift this toast vertically by `delta` px (used by manager for stacking) */\r\n shiftVertical(bottomPx: number): void {\r\n const pos = this.options.position;\r\n if (pos.startsWith('bottom')) {\r\n this.wrapper.style.bottom = `${bottomPx}px`;\r\n } else {\r\n this.wrapper.style.top = `${bottomPx}px`;\r\n }\r\n }\r\n\r\n getWrapperHeight(): number {\r\n return this.wrapper.getBoundingClientRect().height || 90;\r\n }\r\n\r\n // ── DOM builders ───────────────────────────────────────────────────────────\r\n\r\n private buildWrapper(): HTMLDivElement {\r\n const w = document.createElement('div');\r\n const classes = ['robot-toast-wrapper', `robot-toast-${this.options.position}`];\r\n if (this.options.rtl) classes.push('robot-toast-rtl');\r\n w.className = classes.join(' ');\r\n\r\n // ARIA: error/warning are assertive (role=alert), everything else polite (role=status).\r\n const assertive = this.options.type === 'error' || this.options.type === 'warning';\r\n w.setAttribute('role', assertive ? 'alert' : 'status');\r\n w.setAttribute('aria-live', assertive ? 'assertive' : 'polite');\r\n w.setAttribute('aria-atomic', 'true');\r\n\r\n return w;\r\n }\r\n\r\n /**\r\n * Decides what a given `robotVariant` resolves to:\r\n * - `'hidden'` — not shown at all (omitted, '' empty, 'none' alias, or unusable string)\r\n * - `'default'` — built-in inline SVG\r\n * - `'image'` — external image source (data URL or file path)\r\n */\r\n private resolveVariant(): 'hidden' | 'default' | 'image' {\r\n const v = this.options.robotVariant;\r\n if (!v || v === 'none') return 'hidden';\r\n if (v === 'default') return 'default';\r\n const ALLOWED_EXTS = ['.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp'];\r\n const isDataUrl = v.startsWith('data:');\r\n const isAllowed = isDataUrl\r\n || ALLOWED_EXTS.some(ext => v.toLowerCase().endsWith(ext));\r\n return isAllowed ? 'image' : 'hidden';\r\n }\r\n\r\n private buildRobot(): HTMLDivElement {\r\n const r = document.createElement('div');\r\n r.className = 'robot-toast-robot';\r\n\r\n const kind = this.resolveVariant();\r\n\r\n if (kind === 'hidden') {\r\n r.style.display = 'none';\r\n return r;\r\n }\r\n\r\n if (kind === 'default') {\r\n r.innerHTML = this.getBuiltinSVG();\r\n return r;\r\n }\r\n\r\n // kind === 'image' — data URL or recognized path. Fall back to the\r\n // built-in SVG only if the image fails to load at runtime (the user\r\n // clearly intended a robot, so we don't want an empty slot).\r\n const img = document.createElement('img');\r\n img.src = this.options.robotVariant;\r\n img.alt = 'Robot';\r\n img.setAttribute('width', '65');\r\n img.setAttribute('height', '70');\r\n img.style.cssText = 'width:100%;height:100%;object-fit:contain;display:block;';\r\n img.onerror = () => { r.innerHTML = this.getBuiltinSVG(); };\r\n r.appendChild(img);\r\n return r;\r\n }\r\n\r\n private buildMessageBox(): HTMLDivElement {\r\n const box = document.createElement('div');\r\n const classes = [\r\n 'robot-toast-message',\r\n `robot-toast-type-${this.options.type}`,\r\n `robot-toast-theme-${this.options.theme}`,\r\n ].filter(Boolean);\r\n box.className = classes.join(' ');\r\n box.style.cursor = this.options.draggable ? 'grab' : 'default';\r\n\r\n // Apply inline styles if provided (takes precedence over theme colors)\r\n if (this.options.style) {\r\n Object.entries(this.options.style).forEach(([key, value]) => {\r\n const camelCaseKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (box.style as any)[camelCaseKey] = value;\r\n });\r\n }\r\n\r\n // ── Layout ────────────────────────────────────────────────────────────\r\n // Discrete sections, each owning its own spacing. The outer `box` has no\r\n // padding — bodyPad and footerPad live on the sections themselves, so\r\n // optional pieces (footer, progress bar) can appear/disappear without\r\n // us having to juggle conditional margins anywhere else.\r\n\r\n // Close button — absolute, top-right of the whole box (outside sections)\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'robot-toast-close';\r\n closeBtn.innerHTML = '×';\r\n closeBtn.title = 'Dismiss';\r\n closeBtn.type = 'button';\r\n closeBtn.setAttribute('aria-label', 'Dismiss notification');\r\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.close(); });\r\n box.appendChild(closeBtn);\r\n\r\n // Section 1 — body (message text). Always present.\r\n const body = document.createElement('div');\r\n body.className = 'robot-toast-body';\r\n const text = document.createElement('div');\r\n text.className = 'robot-toast-text';\r\n body.appendChild(text);\r\n box.appendChild(body);\r\n\r\n // Section 2 — footer (button rows). Rendered only when buttons exist.\r\n if (this.options.buttons && this.options.buttons.length > 0) {\r\n const footer = document.createElement('div');\r\n footer.className = 'robot-toast-footer';\r\n // Chunk into rows per the layout spec (1→[1] 4→[2,2] 5→[3,2] 7→[3,2,2] …)\r\n // then emit each row with `data-count` so CSS can pick the right split.\r\n const rows = chunkButtons(this.options.buttons);\r\n rows.forEach(rowBtns => {\r\n const row = document.createElement('div');\r\n row.className = 'robot-toast-row';\r\n row.setAttribute('data-count', String(rowBtns.length));\r\n rowBtns.forEach(btn => row.appendChild(this.buildButton(btn)));\r\n footer.appendChild(row);\r\n });\r\n box.appendChild(footer);\r\n }\r\n\r\n // Progress bar — unchanged, always last.\r\n const pContainer = document.createElement('div');\r\n pContainer.className = 'robot-toast-progress-container';\r\n if (this.options.hideProgressBar) pContainer.style.display = 'none';\r\n\r\n const pBar = document.createElement('div');\r\n pBar.className = 'robot-toast-progress-bar';\r\n\r\n pContainer.appendChild(pBar);\r\n box.appendChild(pContainer);\r\n\r\n return box;\r\n }\r\n\r\n private buildButton(button: ToastButton): HTMLButtonElement {\r\n const el = document.createElement('button');\r\n el.type = 'button';\r\n el.className = button.className\r\n ? `robot-toast-btn ${button.className}`\r\n : 'robot-toast-btn';\r\n el.textContent = button.label;\r\n\r\n // Inline style: same kebab → camel conversion the message-level `style`\r\n // option uses, so consumers can pass either form. Applied after className\r\n // so it takes precedence over class-based rules.\r\n if (button.style) {\r\n Object.entries(button.style).forEach(([key, value]) => {\r\n const camelKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (el.style as unknown as Record<string, string | number>)[camelKey] = value;\r\n });\r\n }\r\n\r\n el.addEventListener('click', (e) => {\r\n // Stop the click from bubbling to drag / hover handlers on the wrapper.\r\n e.stopPropagation();\r\n // Fire the callback, then dismiss. If the callback throws we still\r\n // close — otherwise a bad handler strands the toast on screen.\r\n try {\r\n button.onClick(e);\r\n } catch (err) {\r\n console.error('[robot-toast] button onClick threw:', err);\r\n }\r\n this.close();\r\n });\r\n return el;\r\n }\r\n\r\n private assembleLayout(): void {\r\n const { rtl } = this.options;\r\n this.wrapper.innerHTML = '';\r\n\r\n // Decide order: rtl flips everything, robot side controls natural order\r\n const robotOnLeft = rtl ? this.currentRobotSide === 'right' : this.currentRobotSide === 'left';\r\n\r\n if (robotOnLeft) {\r\n this.wrapper.appendChild(this.robotEl);\r\n this.wrapper.appendChild(this.messageBox);\r\n } else {\r\n this.wrapper.appendChild(this.messageBox);\r\n this.wrapper.appendChild(this.robotEl);\r\n }\r\n }\r\n\r\n // ── Sequenced animations ───────────────────────────────────────────────────\r\n\r\n private playEntrance(): void {\r\n // Step 1 – wrapper becomes visible\r\n this.wrapper.classList.add('robot-toast-visible');\r\n\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const showMessage = () => {\r\n if (messageHidden) {\r\n // No text box – skip pop-in, still fire onOpen and start timer\r\n this.options.onOpen?.();\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n // Message pops in\r\n const msgEnterClass = this.options.transition === 'bounce'\r\n ? 'message-enter'\r\n : `message-enter-${this.options.transition}`;\r\n this.messageBox.classList.add(msgEnterClass);\r\n\r\n const onMsgEntered = () => {\r\n this.messageBox.removeEventListener('animationend', onMsgEntered);\r\n this.messageBox.classList.remove(msgEnterClass);\r\n this.messageBox.style.opacity = '1';\r\n this.messageBox.style.transform = 'none';\r\n\r\n this.options.onOpen?.();\r\n this.startTyping();\r\n };\r\n this.messageBox.addEventListener('animationend', onMsgEntered, { once: true });\r\n };\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot entrance, go straight to message\r\n showMessage();\r\n } else {\r\n // Step 2 – robot runs in with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const enterClass = `robot-enter-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(enterClass);\r\n\r\n const onRobotEntered = () => {\r\n this.robotEl.removeEventListener('animationend', onRobotEntered);\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(enterClass);\r\n this.robotEl.classList.add('robot-idle');\r\n showMessage();\r\n };\r\n this.robotEl.addEventListener('animationend', onRobotEntered, { once: true });\r\n }\r\n }\r\n\r\n private playExit(done: () => void): void {\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const afterMsg = () => {\r\n this.messageBox.removeEventListener('animationend', afterMsg);\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot exit, just fade wrapper\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n } else {\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n\r\n // Step 2 – robot runs out with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const exitClass = `robot-exit-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(exitClass);\r\n\r\n const afterRobot = () => {\r\n this.robotEl.removeEventListener('animationend', afterRobot);\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n };\r\n this.robotEl.addEventListener('animationend', afterRobot, { once: true });\r\n }\r\n };\r\n\r\n if (messageHidden) {\r\n // No text box – skip the collapse step entirely\r\n afterMsg();\r\n } else {\r\n this.messageBox.classList.add('message-exit');\r\n this.messageBox.addEventListener('animationend', afterMsg, { once: true });\r\n }\r\n }\r\n\r\n // ── Typing effect ──────────────────────────────────────────────────────────\r\n\r\n private startTyping(): void {\r\n const { message, typeSpeed } = this.options;\r\n const el = this.messageText;\r\n\r\n if (typeSpeed === 0) {\r\n // Instant – no animation\r\n el.textContent = message;\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n\r\n let index = 0;\r\n let active = true;\r\n\r\n // Register cleanup so that if toast is closed mid-type the loop stops\r\n this.cleanupFns.push(() => { active = false; });\r\n\r\n const tick = () => {\r\n if (!active) return;\r\n if (index < message.length) {\r\n el.textContent += message.charAt(index++);\r\n setTimeout(tick, typeSpeed);\r\n } else {\r\n this.afterTypingComplete();\r\n }\r\n };\r\n tick();\r\n }\r\n\r\n private afterTypingComplete(): void {\r\n // Always start auto-progress-bar animation (unless hidden)\r\n if (this.autoCloseDuration > 0 && !this.options.hideProgressBar && this.progressBar) {\r\n this.progressBar.style.animationDuration = `${this.autoCloseDuration}ms`; // set duration FIRST\r\n void this.progressBar.offsetWidth; // flush\r\n this.progressBar.classList.add('robot-toast-progress-auto'); // THEN start\r\n if (this.isHovered || this.isFocusLost) {\r\n this.progressBar.classList.add('robot-toast-progress-paused');\r\n }\r\n }\r\n\r\n // Start the close timer unless something is currently pausing it\r\n if (!this.isHovered && !this.isFocusLost) {\r\n this.startTimer();\r\n }\r\n }\r\n\r\n // ── Timer management ───────────────────────────────────────────────────────\r\n\r\n private startTimer(): void {\r\n if (this.autoCloseDuration <= 0 || this.remainingTime <= 0) return;\r\n this.timerStart = Date.now();\r\n this.closeTimeout = setTimeout(() => this.close(), this.remainingTime);\r\n }\r\n\r\n private pauseTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n if (this.timerStart !== null) {\r\n const elapsed = Date.now() - this.timerStart;\r\n this.remainingTime = Math.max(0, this.remainingTime - elapsed);\r\n this.timerStart = null;\r\n }\r\n }\r\n this.progressBar?.classList.add('robot-toast-progress-paused');\r\n }\r\n\r\n private resumeTimer(): void {\r\n if (this.isHovered || this.isFocusLost || this.isDragging) return;\r\n this.progressBar?.classList.remove('robot-toast-progress-paused');\r\n this.startTimer();\r\n }\r\n\r\n private cancelTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n }\r\n }\r\n\r\n // ── Hover watcher ──────────────────────────────────────────────────────────\r\n\r\n private initHoverWatcher(): void {\r\n const onEnter = () => {\r\n this.isHovered = true;\r\n this.pauseTimer();\r\n };\r\n const onLeave = () => {\r\n this.isHovered = false;\r\n this.resumeTimer();\r\n };\r\n this.wrapper.addEventListener('mouseenter', onEnter);\r\n this.wrapper.addEventListener('mouseleave', onLeave);\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('mouseenter', onEnter);\r\n this.wrapper.removeEventListener('mouseleave', onLeave);\r\n });\r\n }\r\n\r\n // ── Focus watcher ──────────────────────────────────────────────────────────\r\n\r\n private initFocusWatcher(): void {\r\n const onBlur = () => {\r\n this.isFocusLost = true;\r\n this.pauseTimer();\r\n };\r\n const onFocus = () => {\r\n this.isFocusLost = false;\r\n this.resumeTimer();\r\n };\r\n window.addEventListener('blur', onBlur);\r\n window.addEventListener('focus', onFocus);\r\n this.cleanupFns.push(() => {\r\n window.removeEventListener('blur', onBlur);\r\n window.removeEventListener('focus', onFocus);\r\n });\r\n }\r\n\r\n // ── Drag ──────────────────────────────────────────────────────────────────\r\n\r\n private initDrag(): void {\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Pointer events (covers both mouse & touch via pointer API) ──────────\r\n const onPointerDown = (e: PointerEvent) => {\r\n // Clicks / taps on the close button or any inline action button must\r\n // never initiate a drag — otherwise the user can't actually press them.\r\n if ((e.target as HTMLElement).closest(\r\n '.robot-toast-close, .robot-toast-btn'\r\n )) return;\r\n // Only primary button / first touch\r\n if (e.button !== undefined && e.button !== 0) return;\r\n\r\n e.preventDefault();\r\n this.isDragging = true;\r\n this.pauseTimer();\r\n\r\n // \"Detach\" the wrapper from its CSS-positioned slot by converting its\r\n // current visual position into explicit inline top/left values.\r\n const rect = this.wrapper.getBoundingClientRect();\r\n this.wrapper.classList.add('robot-toast-dragging');\r\n\r\n // Inline position so the wrapper sits exactly where it was\r\n this.wrapper.style.top = `${rect.top}px`;\r\n this.wrapper.style.left = `${rect.left}px`;\r\n this.wrapper.style.right = 'auto';\r\n this.wrapper.style.bottom = 'auto';\r\n this.wrapper.style.transform = 'none';\r\n\r\n // Cache size — width/height don't change during drag, so we avoid a\r\n // layout read on every pointermove (major mobile jank source).\r\n this.dragWidth = rect.width;\r\n this.dragHeight = rect.height;\r\n\r\n // Offset = where inside the wrapper the pointer grabbed\r\n this.dragOffsetX = e.clientX - rect.left;\r\n this.dragOffsetY = e.clientY - rect.top;\r\n\r\n this.messageBox.style.cursor = 'grabbing';\r\n this.wrapper.setPointerCapture(e.pointerId);\r\n };\r\n\r\n const onPointerMove = (e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n e.preventDefault();\r\n\r\n // Use cached width/height + live window dims — no layout flush.\r\n const maxX = window.innerWidth - this.dragWidth;\r\n const maxY = window.innerHeight - this.dragHeight;\r\n\r\n const newLeft = Math.max(0, Math.min(e.clientX - this.dragOffsetX, maxX));\r\n const newTop = Math.max(0, Math.min(e.clientY - this.dragOffsetY, maxY));\r\n\r\n this.wrapper.style.left = `${newLeft}px`;\r\n this.wrapper.style.top = `${newTop}px`;\r\n };\r\n\r\n const onPointerUp = (_e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n this.isDragging = false;\r\n this.wrapper.classList.remove('robot-toast-dragging');\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Snap to nearest horizontal screen edge ────────────────────────────\r\n // One getBoundingClientRect() on drop is fine — it's a single layout\r\n // flush per release, not per frame. This is more robust than reading\r\n // inline style.left, which can lag the rendered position in edge cases\r\n // (parent transforms, pending animations, etc.).\r\n const rect = this.wrapper.getBoundingClientRect();\r\n const currentTop = rect.top;\r\n const midX = rect.left + rect.width / 2;\r\n const centerX = window.innerWidth / 2;\r\n\r\n // Determine which edge to snap to based on which half the center is in\r\n const snapToLeft = midX < centerX;\r\n\r\n // Determine robot side based on nearScreen setting\r\n const newRobotSide: 'left' | 'right' = this.options.nearScreen\r\n ? (snapToLeft ? 'left' : 'right')\r\n : (snapToLeft ? 'right' : 'left');\r\n\r\n // Determine final resting left position (20px margin from edge)\r\n const finalLeft = snapToLeft ? 20 : window.innerWidth - this.dragWidth - 20;\r\n const finalTop = Math.max(20, Math.min(currentTop, window.innerHeight - this.dragHeight - 20));\r\n\r\n // Re-enable transitions for the snap glide\r\n this.wrapper.style.transition =\r\n 'left 0.45s cubic-bezier(0.34,1.56,0.64,1), top 0.4s cubic-bezier(0.34,1.56,0.64,1)';\r\n this.wrapper.style.left = `${finalLeft}px`;\r\n this.wrapper.style.top = `${finalTop}px`;\r\n\r\n // Update robot side if it changed\r\n if (newRobotSide !== this.currentRobotSide) {\r\n this.currentRobotSide = newRobotSide;\r\n\r\n // Use CSS order to visually reorder (no DOM detach = no animation restart)\r\n const robotOnLeft = newRobotSide === 'left';\r\n this.robotEl.style.order = robotOnLeft ? '0' : '1';\r\n this.messageBox.style.order = robotOnLeft ? '1' : '0';\r\n\r\n // Snap animation\r\n const snapClass = newRobotSide === 'left' ? 'robot-snap-left' : 'robot-snap-right';\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n this.robotEl.classList.add(snapClass);\r\n this.robotEl.addEventListener('animationend', () => {\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(snapClass);\r\n this.robotEl.classList.add('robot-idle');\r\n }, { once: true });\r\n }\r\n const clearTransition = () => {\r\n this.wrapper.style.transition = '';\r\n };\r\n setTimeout(clearTransition, 500);\r\n\r\n // Resume the auto-close timer\r\n this.resumeTimer();\r\n };\r\n\r\n this.wrapper.addEventListener('pointerdown', onPointerDown);\r\n this.wrapper.addEventListener('pointermove', onPointerMove);\r\n this.wrapper.addEventListener('pointerup', onPointerUp);\r\n this.wrapper.addEventListener('pointercancel', onPointerUp);\r\n\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('pointerdown', onPointerDown);\r\n this.wrapper.removeEventListener('pointermove', onPointerMove);\r\n this.wrapper.removeEventListener('pointerup', onPointerUp);\r\n this.wrapper.removeEventListener('pointercancel', onPointerUp);\r\n });\r\n }\r\n\r\n // ── Built-in robot SVG ─────────────────────────────────────────────────────\r\n\r\n private getBuiltinSVG(): string {\r\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 120\"\r\n width=\"100%\" height=\"100%\" role=\"img\" aria-label=\"Robot\">\r\n <defs>\r\n <linearGradient id=\"rtGrad${this.id}\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#E2F0FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#B8D8FF\"/>\r\n </linearGradient>\r\n <linearGradient id=\"rtAccent${this.id}\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#7CB9FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#4A90D9\"/>\r\n </linearGradient>\r\n </defs>\r\n <!-- Antenna -->\r\n <line x1=\"50\" y1=\"4\" x2=\"50\" y2=\"18\" stroke=\"#2B3A55\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\r\n <circle cx=\"50\" cy=\"4\" r=\"4\" fill=\"#FF6B6B\"/>\r\n <!-- Head -->\r\n <rect x=\"24\" y=\"18\" width=\"52\" height=\"40\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Eyes -->\r\n <circle cx=\"38\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"62\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"40\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <circle cx=\"64\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <!-- Mouth -->\r\n <path d=\"M 38 50 Q 50 58 62 50\" stroke=\"#2B3A55\" stroke-width=\"2\"\r\n fill=\"none\" stroke-linecap=\"round\"/>\r\n <!-- Neck -->\r\n <rect x=\"44\" y=\"58\" width=\"12\" height=\"8\" rx=\"3\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <!-- Body -->\r\n <rect x=\"22\" y=\"66\" width=\"56\" height=\"44\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Chest panel -->\r\n <rect x=\"34\" y=\"76\" width=\"32\" height=\"20\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <circle cx=\"42\" cy=\"86\" r=\"3\" fill=\"#FF6B6B\"/>\r\n <circle cx=\"50\" cy=\"86\" r=\"3\" fill=\"#FFD700\"/>\r\n <circle cx=\"58\" cy=\"86\" r=\"3\" fill=\"#6BFF8A\"/>\r\n <!-- Arms -->\r\n <rect x=\"4\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <rect x=\"78\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Legs -->\r\n <rect x=\"30\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <rect x=\"54\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n </svg>`;\r\n }\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n RobotToastManager – global singleton that owns all ToastItems\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass RobotToastManager {\r\n private static _instance: RobotToastManager | null = null;\r\n\r\n private activeToasts: ToastItem[] = [];\r\n private queue: ToastQueueItem[] = [];\r\n private globalLimit = 0; // 0 = unlimited; overridden per-show call\r\n\r\n private constructor() {\r\n new InjectStyles();\r\n }\r\n\r\n static getInstance(): RobotToastManager {\r\n if (!RobotToastManager._instance) {\r\n RobotToastManager._instance = new RobotToastManager();\r\n }\r\n return RobotToastManager._instance;\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n show(options: RobotToastOptions): number {\r\n if (typeof document === 'undefined') return -1;\r\n\r\n const id = nextId();\r\n const limit = options.limit ?? this.globalLimit;\r\n\r\n if (limit > 0 && this.activeToasts.length >= limit) {\r\n // Queue it for later\r\n this.queue.push({ options, id });\r\n return id;\r\n }\r\n\r\n this.spawnToast(options, id);\r\n return id;\r\n }\r\n\r\n closeAll(): void {\r\n this.queue = [];\r\n [...this.activeToasts].forEach(t => t.close());\r\n }\r\n\r\n closeById(id: number): void {\r\n const toast = this.activeToasts.find(t => t.id === id);\r\n if (toast) toast.close();\r\n\r\n // Also remove from queue if it hasn't spawned yet\r\n this.queue = this.queue.filter(q => q.id !== id);\r\n }\r\n\r\n // ── Internal ───────────────────────────────────────────────────────────────\r\n\r\n private spawnToast(options: RobotToastOptions, id: number): void {\r\n const toast = new ToastItem(id, options, (doneId) => this.handleRemoved(doneId));\r\n const newestOnTop = options.newestOnTop ?? false;\r\n\r\n if (newestOnTop) {\r\n this.activeToasts.unshift(toast);\r\n } else {\r\n this.activeToasts.push(toast);\r\n }\r\n\r\n this.restack();\r\n }\r\n\r\n private handleRemoved(id: number): void {\r\n this.activeToasts = this.activeToasts.filter(t => t.id !== id);\r\n this.restack();\r\n\r\n // Dequeue next if any\r\n if (this.queue.length > 0) {\r\n const next = this.queue.shift()!;\r\n // Small delay so the stack reflows are visible\r\n setTimeout(() => this.spawnToast(next.options, next.id), 120);\r\n }\r\n }\r\n\r\n /**\r\n * Recalculate the vertical position of every active toast so they stack\r\n * neatly without overlap. Works for both top-* and bottom-* positions.\r\n */\r\n private restack(): void {\r\n // Group by position string\r\n const groups: Record<string, ToastItem[]> = {};\r\n this.activeToasts.forEach(t => {\r\n const pos = (t as any).options.position as string;\r\n if (!groups[pos]) groups[pos] = [];\r\n groups[pos].push(t);\r\n });\r\n\r\n Object.keys(groups).forEach(pos => {\r\n const list = groups[pos];\r\n let offset = 20; // initial edge margin px\r\n\r\n list.forEach((toast) => {\r\n toast.shiftVertical(offset);\r\n offset += toast.getWrapperHeight() + STACK_GAP;\r\n });\r\n });\r\n }\r\n}\r\n\r\nexport { RobotToastManager as default, RobotToastManager };","/**\r\n * RobotToast Utilities v2\r\n * Helper functions for safer access to the RobotToast API.\r\n * Handles async readiness checks, SSR guards, and error boundaries.\r\n * Useful when loading robot-toast via a CDN <script> tag.\r\n */\r\n\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\n\r\n/**\r\n * Wait for window.RobotToast to be available, up to `timeout` ms.\r\n * Resolves immediately if it is already loaded.\r\n * Useful when the library is loaded via a <script> tag and you need\r\n * to call it from another script that may execute first.\r\n */\r\nexport function ensureRobotToastReady(timeout = 5000): Promise<RobotToastAPI> {\r\n return new Promise((resolve, reject) => {\r\n if (typeof window === 'undefined') {\r\n reject(new Error('[RobotToast] Cannot run outside of a browser environment.'));\r\n return;\r\n }\r\n\r\n if (window.RobotToast) {\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n const interval = setInterval(() => {\r\n if (window.RobotToast) {\r\n clearInterval(interval);\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n if (Date.now() - startTime >= timeout) {\r\n clearInterval(interval);\r\n reject(new Error(`[RobotToast] Failed to load within ${timeout}ms.`));\r\n }\r\n }, 80);\r\n });\r\n}\r\n\r\n/**\r\n * Show a robot toast notification.\r\n * Waits for the library to be ready before showing.\r\n * Returns the toast id or -1 on failure.\r\n */\r\nexport async function showRobotToast(options: RobotToastOptions): Promise<number> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n return api.show(options);\r\n } catch (err) {\r\n console.error('[RobotToast] showRobotToast failed:', err);\r\n return -1;\r\n }\r\n}\r\n\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\nexport async function closeAllRobotToasts(): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeAll();\r\n } catch (err) {\r\n console.error('[RobotToast] closeAllRobotToasts failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Close a specific toast by the id returned from show().\r\n */\r\nexport async function closeRobotToastById(id: number): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeById(id);\r\n } catch (err) {\r\n console.error('[RobotToast] closeRobotToastById failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Get the RobotToast API instance.\r\n */\r\nexport async function getRobotToastInstance(): Promise<RobotToastAPI> {\r\n return ensureRobotToastReady();\r\n}","/**\r\n * RobotToast Types & Constants\r\n * Type definitions and constant arrays for the robot toast notification library\r\n */\r\n\r\n/** Array of all valid toast positions */\r\nexport const TOAST_POSITIONS = [\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] as const;\r\n\r\n/** Array of all valid toast types */\r\nexport const TOAST_TYPES = ['default', 'info', 'success', 'warning', 'error'] as const;\r\n\r\n/** Array of all valid toast themes */\r\nexport const TOAST_THEMES = ['light', 'dark', 'colored'] as const;\r\n\r\n/** Array of all valid transition animations */\r\nexport const TOAST_TRANSITIONS = ['bounce', 'slide', 'zoom', 'flip'] as const;\r\n\r\n/** Type derived from TOAST_POSITIONS constant */\r\nexport type ToastPosition = typeof TOAST_POSITIONS[number];\r\n\r\n/** Type derived from TOAST_TYPES constant */\r\nexport type ToastType = typeof TOAST_TYPES[number];\r\n\r\n/** Type derived from TOAST_THEMES constant */\r\nexport type ToastTheme = typeof TOAST_THEMES[number];\r\n\r\n/** Type derived from TOAST_TRANSITIONS constant */\r\nexport type TransitionType = typeof TOAST_TRANSITIONS[number];\r\n\r\n/**\r\n * A button rendered inside the toast. Pass an array of these as `buttons`\r\n * to add inline CTAs like \"Undo\" / \"Retry\" / \"Cancel\":\r\n *\r\n * toast({\r\n * message: 'File deleted',\r\n * buttons: [\r\n * { label: 'Undo', onClick: () => restore() },\r\n * ],\r\n * });\r\n *\r\n * Buttons render in array order. Clicking any of them fires its `onClick`\r\n * and then closes the toast. Visual hierarchy is up to you — pass a custom\r\n * `className` to override the default neutral style (e.g. to mark the\r\n * primary CTA as filled/bold and a secondary as muted).\r\n */\r\nexport interface ToastButton {\r\n /** Visible button text. Keep it short (1–2 words). */\r\n label: string;\r\n /** Fired before the toast closes. Receives the click event. */\r\n onClick: (event: MouseEvent) => void;\r\n /**\r\n * Optional CSS class(es) appended to the button element. Use this when you\r\n * have a stylesheet rule like `.my-primary { background: black; color: white }`\r\n * defined elsewhere in your app and want to apply it to this button.\r\n */\r\n className?: string;\r\n /**\r\n * Optional inline styles applied directly to the button element. Use this\r\n * when you don't want to add a CSS rule to your stylesheet — pass an object\r\n * of camelCased properties (or kebab-case keys; both work):\r\n *\r\n * style: { background: 'black', color: 'white', borderRadius: '8px' }\r\n *\r\n * Takes precedence over className-based rules and over the default neutral\r\n * (and solo-CTA) button styles.\r\n */\r\n style?: Record<string, string | number>;\r\n}\r\n\r\nexport interface RobotToastOptions {\r\n /** The message text to display in the toast */\r\n message: string;\r\n\r\n /** Auto-close duration in ms, or false to disable. Default: 5000 */\r\n autoClose?: boolean | number;\r\n\r\n /** Position of the toast on screen. Default: 'bottom-right' */\r\n position?: ToastPosition;\r\n\r\n /** Toast type/style. Default: 'default' */\r\n type?: ToastType;\r\n\r\n /** Visual theme. Default: 'light' */\r\n theme?: ToastTheme;\r\n\r\n /**\r\n * Inline style object to apply directly to the message box element.\r\n * This allows runtime customization of colors, fonts, backgrounds, etc.\r\n * Example: { color: 'red', backgroundColor: 'blue' }\r\n * This takes precedence over className for conflicting properties.\r\n */\r\n style?: Record<string, string | number>;\r\n\r\n /** Typing speed in ms per character. 0 = instant. Default: 30 */\r\n typeSpeed?: number;\r\n\r\n /**\r\n * Robot image source. Opt-in — nothing is shown unless you ask for one.\r\n * Pass one of:\r\n * - Omit (or pass `undefined` / `''` / `'none'`) to hide the robot entirely.\r\n * - `'default'` to render the built-in inline SVG (no network fetch).\r\n * - A data URL from `robot-toast/robots` (tree-shakeable, recommended):\r\n * import { wave } from 'robot-toast/robots';\r\n * toast({ message: 'Hi', robotVariant: wave });\r\n * - A path to an image file (svg/png/jpg/jpeg/gif/webp).\r\n * Unrecognized values are treated as \"hidden\" rather than rendered.\r\n */\r\n robotVariant?: string;\r\n\r\n /** Hide the countdown progress bar. Default: false */\r\n hideProgressBar?: boolean;\r\n\r\n /** Pause the auto-close countdown when the window loses focus. Default: true */\r\n pauseOnFocusLoss?: boolean;\r\n\r\n /** Allow the user to drag the toast around the screen. Default: true */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Position the robot near the screen edge (true) or away from it (false).\r\n * - true: robot appears between screen edge and message bubble\r\n * - false: message bubble appears between screen edge and robot\r\n * The position is automatically determined by the toast position and this setting.\r\n * Default: true\r\n */\r\n nearScreen?: boolean;\r\n\r\n /** Pause the auto-close countdown while the cursor is over the toast. Default: true */\r\n pauseOnHover?: boolean;\r\n\r\n /**\r\n * Maximum number of toasts visible simultaneously.\r\n * Excess toasts are queued and shown as soon as a slot opens.\r\n * 0 = unlimited (queue still works, all show in parallel). Default: 0\r\n */\r\n limit?: number;\r\n\r\n /** Stack newest toasts on top of older ones. Default: false */\r\n newestOnTop?: boolean;\r\n\r\n /** Right-to-left layout (message on the right, robot on the left). Default: false */\r\n rtl?: boolean;\r\n\r\n /** Entry / exit transition style. Default: 'bounce' */\r\n transition?: TransitionType;\r\n\r\n /**\r\n * Inline buttons to render inside the toast (e.g. Undo, Retry, Cancel).\r\n * Rendered in array order. Each click fires the button's `onClick` and\r\n * then closes the toast automatically.\r\n */\r\n buttons?: ToastButton[];\r\n\r\n /** Called when the toast finishes its enter animation and is fully visible. */\r\n onOpen?: () => void;\r\n\r\n /** Called after the toast has fully exited the screen. */\r\n onClose?: () => void;\r\n}\r\n\r\n/** Internal representation of a queued toast item */\r\nexport interface ToastQueueItem {\r\n options: RobotToastOptions;\r\n id: number;\r\n}\r\n\r\nexport interface RobotToastAPI {\r\n /** Show a toast notification – queued automatically when limit is reached */\r\n show: (options: RobotToastOptions) => number;\r\n /** Immediately close all visible toasts and clear the queue */\r\n closeAll: () => void;\r\n /** Close a specific toast by the id returned from show() */\r\n closeById: (id: number) => void;\r\n /** Get the RobotToastManager instance */\r\n getInstance: () => RobotToastInstance;\r\n}\r\n\r\nexport interface RobotToastInstance {\r\n show: (options: RobotToastOptions) => number;\r\n closeAll: () => void;\r\n closeById: (id: number) => void;\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n __robotToastLoaded?: boolean;\r\n __robotToastUtilsLoaded?: boolean;\r\n RobotToast?: RobotToastAPI;\r\n RobotToastUtils?: {\r\n showRobotToast: (options: RobotToastOptions) => Promise<number>;\r\n closeAllRobotToasts: () => Promise<void>;\r\n closeRobotToastById: (id: number) => Promise<void>;\r\n getRobotToastInstance: () => Promise<RobotToastAPI>;\r\n ensureRobotToastReady: (timeout?: number) => Promise<RobotToastAPI>;\r\n };\r\n }\r\n}","/**\r\n * robot-toast v2\r\n * A lightweight, framework-agnostic toast notification library\r\n * with an animated robot character, multi-toast queue, and smooth drag.\r\n *\r\n * ── Basic usage ──────────────────────────────────────────────────────────────\r\n * import { toast } from 'robot-toast';\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', position: 'top-right', type: 'success' });\r\n *\r\n * ── Typed shorthands ─────────────────────────────────────────────────────────\r\n * toast.success('Saved!');\r\n * toast.error('Something went wrong');\r\n * toast.info('Did you know…');\r\n * toast.warning('Check your input');\r\n *\r\n * ── Class / manager ──────────────────────────────────────────────────────────\r\n * import { RobotToast } from 'robot-toast';\r\n * const manager = RobotToast.getInstance();\r\n * const id = manager.show({ message: 'Hi!' });\r\n * manager.closeById(id);\r\n */\r\n\r\nimport RobotToastManager from './toast';\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\nimport './styles-injector'; // Auto-inject styles\r\n\r\n// ─── Core show function ────────────────────────────────────────────────────\r\n\r\ntype ToastInput = string | RobotToastOptions;\r\n\r\nfunction normalise(input: ToastInput): RobotToastOptions {\r\n return typeof input === 'string' ? { message: input } : input;\r\n}\r\n\r\n/**\r\n * Show a toast notification.\r\n * Accepts either a plain string or a full options object.\r\n * Returns the toast id (useful for closeById).\r\n *\r\n * @example\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', type: 'success', position: 'top-right' });\r\n */\r\nfunction toast(input: ToastInput): number {\r\n if (typeof window === 'undefined') return -1;\r\n return RobotToastManager.getInstance().show(normalise(input));\r\n}\r\n\r\n// ── Typed shorthand helpers ───────────────────────────────────────────────────\r\ntoast.success = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'success' });\r\n\r\ntoast.error = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'error' });\r\n\r\ntoast.info = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'info' });\r\n\r\ntoast.warning = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'warning' });\r\n\r\n// ── Close helpers ─────────────────────────────────────────────────────────────\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\ntoast.closeAll = (): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeAll();\r\n};\r\n\r\n/**\r\n * Close a specific toast by the id returned from toast() / toast.show().\r\n */\r\ntoast.closeById = (id: number): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeById(id);\r\n};\r\n\r\n// ── Promise helper ────────────────────────────────────────────────────────────\r\n\r\ntype PromiseMessage<T, E = unknown> = {\r\n loading: string | Partial<RobotToastOptions>;\r\n success: string | ((value: T) => string | Partial<RobotToastOptions>);\r\n error: string | ((err: E) => string | Partial<RobotToastOptions>);\r\n};\r\n\r\n/**\r\n * Attach a toast lifecycle to a promise.\r\n * Shows a persistent `loading` toast; on settlement, closes it and shows a\r\n * `success` or `error` toast. Returns the original promise unchanged so\r\n * callers can still await / chain it.\r\n *\r\n * @example\r\n * toast.promise(fetch('/api/save'), {\r\n * loading: 'Saving…',\r\n * success: 'Saved!',\r\n * error: 'Save failed',\r\n * });\r\n */\r\ntoast.promise = <T, E = unknown>(\r\n promise: Promise<T>,\r\n messages: PromiseMessage<T, E>,\r\n): Promise<T> => {\r\n if (typeof window === 'undefined') return promise;\r\n\r\n const loadingOpts: RobotToastOptions =\r\n typeof messages.loading === 'string'\r\n ? { message: messages.loading }\r\n : { message: '', ...messages.loading };\r\n\r\n const loadingId = toast({\r\n autoClose: false,\r\n hideProgressBar: true,\r\n ...loadingOpts,\r\n // Override typeSpeed for loading so the text appears immediately — a loading\r\n // state that types letter-by-letter feels wrong.\r\n typeSpeed: loadingOpts.typeSpeed ?? 0,\r\n });\r\n\r\n const resolveOptions = (\r\n v: string | Partial<RobotToastOptions>,\r\n fallbackType: RobotToastOptions['type'],\r\n ): RobotToastOptions => {\r\n const base = typeof v === 'string' ? { message: v } : { message: '', ...v };\r\n return { type: fallbackType, ...base };\r\n };\r\n\r\n return promise.then(\r\n (value) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.success === 'function'\r\n ? messages.success(value)\r\n : messages.success;\r\n toast(resolveOptions(next, 'success'));\r\n return value;\r\n },\r\n (err: E) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.error === 'function'\r\n ? messages.error(err)\r\n : messages.error;\r\n toast(resolveOptions(next, 'error'));\r\n throw err;\r\n },\r\n );\r\n};\r\n\r\nexport { toast };\r\n\r\n// ─── Class export ──────────────────────────────────────────────────────────\r\n\r\nexport { default as RobotToast, RobotToastManager } from './toast';\r\n\r\n// ─── Utilities ─────────────────────────────────────────────────────────────\r\n\r\nexport {\r\n ensureRobotToastReady,\r\n showRobotToast,\r\n closeAllRobotToasts,\r\n getRobotToastInstance,\r\n} from './utils';\r\n\r\n// ─── Types ─────────────────────────────────────────────────────────────────\r\n\r\nexport type {\r\n RobotToastOptions,\r\n RobotToastAPI,\r\n RobotToastInstance,\r\n ToastQueueItem,\r\n ToastPosition,\r\n ToastType,\r\n ToastTheme,\r\n TransitionType,\r\n} from './types';\r\n\r\nexport {\r\n TOAST_POSITIONS,\r\n TOAST_TYPES,\r\n TOAST_THEMES,\r\n TOAST_TRANSITIONS,\r\n} from './types';\r\n\r\n// ─── Global registration (for script-tag / CDN usage) ──────────────────────\r\n\r\nfunction registerGlobal(): void {\r\n if (typeof window === 'undefined') return;\r\n if (window.__robotToastLoaded) return;\r\n window.__robotToastLoaded = true;\r\n\r\n const api: RobotToastAPI = {\r\n show: (options: RobotToastOptions) => RobotToastManager.getInstance().show(options),\r\n closeAll: () => RobotToastManager.getInstance().closeAll(),\r\n closeById: (id: number) => RobotToastManager.getInstance().closeById(id),\r\n getInstance: () => RobotToastManager.getInstance(),\r\n };\r\n\r\n window.RobotToast = api;\r\n}\r\n\r\nregisterGlobal();"]}
|
|
1
|
+
{"version":3,"sources":["../src/styles-injector.ts","../src/toast.ts","../src/utils.ts","../src/types.ts","../src/index.ts"],"names":["_InjectStyles","styleId","styles","styleElement","InjectStyles","styles_injector_default","_nextId","nextId","STACK_GAP","chunkButtons","buttons","n","rows","i","ToastItem","id","options","onRemove","resolved","positionIsLeft","initialSide","fn","bottomPx","w","classes","assertive","v","ALLOWED_EXTS","ext","r","kind","img","box","key","value","camelCaseKey","g","closeBtn","e","body","text","footer","rowBtns","row","btn","pContainer","pBar","button","el","camelKey","err","rtl","robotHidden","messageHidden","showMessage","msgEnterClass","onMsgEntered","side","transitionSuffix","enterClass","onRobotEntered","done","afterMsg","exitClass","afterRobot","message","typeSpeed","index","active","tick","elapsed","onEnter","onLeave","onBlur","onFocus","onPointerDown","rect","onPointerMove","maxX","maxY","newLeft","newTop","onPointerUp","_e","currentTop","midX","centerX","snapToLeft","newRobotSide","finalLeft","finalTop","robotOnLeft","snapClass","_RobotToastManager","limit","toast","t","q","doneId","next","groups","pos","list","offset","RobotToastManager","ensureRobotToastReady","timeout","resolve","reject","startTime","interval","showRobotToast","closeAllRobotToasts","getRobotToastInstance","TOAST_POSITIONS","TOAST_TYPES","TOAST_THEMES","TOAST_TRANSITIONS","normalise","input","promise","messages","loadingOpts","loadingId","resolveOptions","fallbackType","base","registerGlobal","api"],"mappings":"aAKA,IAAMA,CAAAA,CAAN,MAAMA,CAAa,CAGjB,WAAA,EAAc,CACR,OAAO,QAAA,CAAa,GAAA,EAAeA,CAAAA,CAAa,QAAA,GAIpDA,CAAAA,CAAa,SAAW,IAAA,CACxB,IAAA,CAAK,SAAA,EAAU,EACjB,CAEQ,SAAA,EAAkB,CACxB,IAAMC,CAAAA,CAAU,oBAAA,CAGhB,GAAI,QAAA,CAAS,cAAA,CAAeA,CAAO,CAAA,CACjC,OAGF,IAAMC,CAAAA,CAAS;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CAkvBTC,CAAAA,CAAe,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","file":"index.js","sourcesContent":["/**\r\n * Style injection for RobotToast\r\n * Injects all required CSS into the document when instantiated\r\n */\r\n\r\nclass InjectStyles {\r\n private static injected = false;\r\n\r\n constructor() {\r\n if (typeof document === 'undefined' || InjectStyles.injected) {\r\n return;\r\n }\r\n\r\n InjectStyles.injected = true;\r\n this.injectCSS();\r\n }\r\n\r\n private injectCSS(): void {\r\n const styleId = 'robot-toast-styles';\r\n\r\n // Check if styles already exist\r\n if (document.getElementById(styleId)) {\r\n return;\r\n }\r\n\r\n const styles = `\r\n/* RobotToast v2 - CSS Styles */\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* WRAPPER - Fixed positioning container for each toast */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-wrapper {\r\n position: fixed;\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n opacity: 0;\r\n z-index: 99999;\r\n pointer-events: auto;\r\n touch-action: none;\r\n -webkit-user-select: none;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-visible {\r\n opacity: 1;\r\n}\r\n\r\n/* Position presets */\r\n.robot-toast-wrapper.robot-toast-top-right {\r\n top: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-left {\r\n top: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-center {\r\n top: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-right {\r\n bottom: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-left {\r\n bottom: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-center {\r\n bottom: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-rtl {\r\n direction: rtl;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-dragging .robot-toast-message {\r\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ROBOT - The animated character */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-robot {\r\n width: 65px;\r\n height: 70px;\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0;\r\n}\r\n\r\n.robot-toast-robot img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-left {\r\n animation: robot-enter-left 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right {\r\n animation: robot-enter-right 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left {\r\n animation: robot-exit-left 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right {\r\n animation: robot-exit-right 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-idle {\r\n opacity: 1;\r\n animation: robot-idle 2s ease-in-out infinite;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-left {\r\n animation: robot-snap-left 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-right {\r\n animation: robot-snap-right 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* MESSAGE BOX - Toast content container */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-message {\r\n position: relative;\r\n width: fit-content;\r\n min-width: 120px;\r\n max-width: min(400px, calc(100vw - 120px));\r\n /*\r\n * IMPORTANT: no padding on the outer box. Each section (.robot-toast-body,\r\n * .robot-toast-footer, .robot-toast-progress-container) owns its own\r\n * spacing, so optional sections can disappear without us having to tweak\r\n * margins / paddings anywhere else.\r\n */\r\n padding: 0;\r\n border-radius: 8px;\r\n margin: 0;\r\n opacity: 0;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\r\n user-select: none;\r\n cursor: default;\r\n box-sizing: border-box;\r\n}\r\n\r\n.robot-toast-message.robot-toast-empty {\r\n display: none;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light {\r\n background: #ffffff;\r\n color: #333333;\r\n border: 1px solid #e0e0e0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark {\r\n background: #2d2d2d;\r\n color: #f0f0f0;\r\n border: 1px solid #444444;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored {\r\n color: #ffffff;\r\n}\r\n\r\n/* Type-specific colors for colored theme */\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-default {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-info {\r\n background: linear-gradient(135deg, #2193b0 0%, #6dd5ed 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-success {\r\n background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-warning {\r\n background: linear-gradient(135deg, #fb6e3b 0%, #f5a623 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-error {\r\n background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);\r\n}\r\n\r\n/* Light theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-info {\r\n border-left: 4px solid #2193b0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-success {\r\n border-left: 4px solid #11998e;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-warning {\r\n border-left: 4px solid #fb6e3b;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-error {\r\n border-left: 4px solid #eb3349;\r\n}\r\n\r\n/* Dark theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-info {\r\n border-left: 4px solid #6dd5ed;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-success {\r\n border-left: 4px solid #38ef7d;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-warning {\r\n border-left: 4px solid #f5a623;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-error {\r\n border-left: 4px solid #f45c43;\r\n}\r\n\r\n.robot-toast-message.message-enter {\r\n animation: message-enter 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-message.message-exit {\r\n animation: message-exit 0.3s ease-in forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* CLOSE BUTTON */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-close {\r\n position: absolute;\r\n top: 4px;\r\n right: 4px;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n line-height: 1;\r\n font-family: Arial, sans-serif;\r\n cursor: pointer;\r\n opacity: 0.6;\r\n transition: opacity 0.2s;\r\n padding: 0;\r\n width: 28px;\r\n height: 28px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: currentColor;\r\n}\r\n\r\n.robot-toast-close:hover {\r\n opacity: 1;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* DRAG HINT */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-drag-hint {\r\n position: absolute;\r\n left: 8px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 3px;\r\n opacity: 0.4;\r\n}\r\n\r\n.robot-toast-drag-hint span {\r\n display: block;\r\n width: 4px;\r\n height: 4px;\r\n border-radius: 50%;\r\n background: currentColor;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* BODY — the message zone. Always present, always owns its own padding. */\r\n/* Right padding leaves clear room for the absolute close button. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-body {\r\n padding: 10px 40px 10px 14px;\r\n}\r\n\r\n.robot-toast-text {\r\n font-size: 14px;\r\n line-height: 1.5;\r\n word-break: break-word;\r\n white-space: pre-wrap;\r\n font-weight: 500;\r\n min-width: 0;\r\n min-height: 1.5em;\r\n /* No padding-bottom here — body's padding-bottom handles spacing toward\r\n whichever section follows (footer, progress bar, or nothing). */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* FOOTER — the button zone. Rendered only when buttons.length > 0. */\r\n/* Owns its own bottom padding so there are no conditional margins anywhere. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-footer {\r\n /*\r\n * Symmetric vertical padding (10px top + 10px bottom) — matches body so\r\n * the two sections feel like equally-weighted \"cards\" stacked inside the\r\n * toast. This is intentional even though it doubles the gap between text\r\n * and buttons (10 body-bottom + 10 footer-top = 20px); the visual balance\r\n * matters more than the gap-tightness.\r\n */\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n}\r\n\r\n/* A row inside the footer. data-count drives width distribution — pure CSS,\r\n * no JS-side layout code. */\r\n.robot-toast-row {\r\n display: flex;\r\n gap: 6px;\r\n align-items: center;\r\n}\r\n\r\n/* 1 button in its row → content-sized, left-aligned (flex default) */\r\n.robot-toast-row[data-count=\"1\"] .robot-toast-btn {\r\n /* nothing — intrinsic width, flex-start alignment */\r\n}\r\n\r\n/* 2 or 3 buttons in a row → equal shares, filling the row's width */\r\n.robot-toast-row[data-count=\"2\"] .robot-toast-btn,\r\n.robot-toast-row[data-count=\"3\"] .robot-toast-btn {\r\n flex: 1;\r\n min-width: 0; /* let long labels shrink without breaking the 50/50 split */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* INLINE BUTTONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-btn {\r\n appearance: none;\r\n font: inherit;\r\n font-size: 12px;\r\n font-weight: 500;\r\n line-height: 1;\r\n padding: 6px 12px;\r\n border-radius: 5px;\r\n cursor: pointer;\r\n transition: background 0.15s ease, color 0.15s ease, transform 0.05s ease;\r\n white-space: nowrap;\r\n background: transparent;\r\n color: #52525b;\r\n border: 1px solid #e4e4e7;\r\n}\r\n.robot-toast-btn:hover { background: #f4f4f5; color: #18181b; }\r\n.robot-toast-btn:active { transform: scale(0.97); }\r\n\r\n/*\r\n * Solo CTA: when the toast has exactly one button, it's implicitly the\r\n * primary action. Render it filled/dark so it feels decisive (Undo / Retry\r\n * UX). A multi-button toast drops back to all-neutral — the caller picks a\r\n * primary via its own className.\r\n *\r\n * \"Exactly one button total\" = the single row has data-count=\"1\" AND is the\r\n * only row in the footer (covers the n=1 case; n=4 also has data-count rows\r\n * but they're paired, not only-child).\r\n */\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #18181b;\r\n color: #fafafa;\r\n border-color: #18181b;\r\n font-weight: 600;\r\n}\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #000;\r\n border-color: #000;\r\n color: #fafafa;\r\n}\r\n\r\n/* Dark theme — inverted neutral */\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn {\r\n color: #a1a1aa;\r\n border-color: #3f3f46;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn:hover {\r\n background: #27272a;\r\n color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #fafafa;\r\n color: #18181b;\r\n border-color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #e4e4e7;\r\n border-color: #e4e4e7;\r\n color: #18181b;\r\n}\r\n\r\n/* Colored theme — translucent whites keep contrast on any gradient */\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn {\r\n color: rgba(255, 255, 255, 0.9);\r\n border-color: rgba(255, 255, 255, 0.35);\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn:hover {\r\n background: rgba(255, 255, 255, 0.15);\r\n color: #fff;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: rgba(255, 255, 255, 0.95);\r\n color: #18181b;\r\n border-color: transparent;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #fff;\r\n color: #18181b;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* PROGRESS BAR */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-progress-container {\r\n width: 100%;\r\n height: 3px;\r\n background: rgba(0, 0, 0, 0.1);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-progress-container {\r\n background: rgba(255, 255, 255, 0.15);\r\n}\r\n\r\n.robot-toast-progress-bar {\r\n height: 100%;\r\n background: currentColor;\r\n transform-origin: left;\r\n transform: scaleX(1); /* ← starts full */\r\n}\r\n\r\n.robot-toast-theme-light.robot-toast-type-success .robot-toast-progress-bar { background: #11998e; }\r\n.robot-toast-theme-light.robot-toast-type-error .robot-toast-progress-bar { background: #eb3349; }\r\n.robot-toast-theme-light.robot-toast-type-warning .robot-toast-progress-bar { background: #fb6e3b; }\r\n.robot-toast-theme-light.robot-toast-type-info .robot-toast-progress-bar { background: #2193b0; }\r\n\r\n/* Dark theme progress bar colors */\r\n.robot-toast-theme-dark.robot-toast-type-success .robot-toast-progress-bar { background: #38ef7d; }\r\n.robot-toast-theme-dark.robot-toast-type-error .robot-toast-progress-bar { background: #f45c43; }\r\n.robot-toast-theme-dark.robot-toast-type-warning .robot-toast-progress-bar { background: #f5a623; }\r\n.robot-toast-theme-dark.robot-toast-type-info .robot-toast-progress-bar { background: #6dd5ed; }\r\n\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-auto {\r\n animation: robot-progress-countdown linear forwards;\r\n opacity: 0.8;\r\n}\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-paused {\r\n animation-play-state: paused !important;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ANIMATIONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n@keyframes robot-enter-left {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-enter-right {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-left {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n@keyframes robot-exit-right {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n\r\n@keyframes robot-idle {\r\n 0%, 100% {\r\n transform: translateY(0);\r\n }\r\n 50% {\r\n transform: translateY(-4px);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-left {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-right {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes message-enter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n@keyframes message-exit {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n}\r\n\r\n@keyframes robot-progress-countdown {\r\n from { transform: scaleX(1); }\r\n to { transform: scaleX(0); }\r\n}\r\n\r\n/* Slide transition animations */\r\n.robot-toast-robot.robot-enter-left-slide {\r\n animation: robot-enter-left-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-slide {\r\n animation: robot-enter-right-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-slide {\r\n animation: robot-exit-left-slide 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-slide {\r\n animation: robot-exit-right-slide 0.4s ease-in forwards;\r\n}\r\n\r\n/* Zoom transition animations */\r\n.robot-toast-robot.robot-enter-left-zoom,\r\n.robot-toast-robot.robot-enter-right-zoom {\r\n animation: robot-enter-zoom 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-zoom,\r\n.robot-toast-robot.robot-exit-right-zoom {\r\n animation: robot-exit-zoom 0.4s ease-in forwards;\r\n}\r\n\r\n/* Flip transition animations */\r\n.robot-toast-robot.robot-enter-left-flip {\r\n animation: robot-enter-left-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-flip {\r\n animation: robot-enter-right-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-flip {\r\n animation: robot-exit-left-flip 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-flip {\r\n animation: robot-exit-right-flip 0.4s ease-in forwards;\r\n}\r\n\r\n@keyframes robot-enter-left-slide {\r\n from { opacity: 0; transform: translateX(-60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-enter-right-slide {\r\n from { opacity: 0; transform: translateX(60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-exit-left-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(-60px); }\r\n}\r\n\r\n@keyframes robot-exit-right-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(60px); }\r\n}\r\n\r\n@keyframes robot-enter-zoom {\r\n from { opacity: 0; transform: scale(0.2); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-zoom {\r\n from { opacity: 1; transform: scale(1); }\r\n to { opacity: 0; transform: scale(0.2); }\r\n}\r\n\r\n@keyframes robot-enter-left-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-enter-right-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-exit-left-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n}\r\n\r\n@keyframes robot-exit-right-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n}\r\n\r\n/* message-enter variants */\r\n.robot-toast-message.message-enter-slide {\r\n animation: message-enter-slide 0.35s ease-out forwards;\r\n}\r\n.robot-toast-message.message-enter-zoom {\r\n animation: message-enter-zoom 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n.robot-toast-message.message-enter-flip {\r\n animation: message-enter-flip 0.4s ease-out forwards;\r\n}\r\n\r\n@keyframes message-enter-slide {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n@keyframes message-enter-zoom {\r\n from { opacity: 0; transform: scale(0.5); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n@keyframes message-enter-flip {\r\n from { opacity: 0; transform: perspective(400px) rotateX(-20deg); }\r\n to { opacity: 1; transform: perspective(400px) rotateX(0deg); }\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* RESPONSIVE - Mobile / small-screen tweaks */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n/*\r\n * Small-viewport tweaks. No !important / edge-to-edge override here — the\r\n * wrapper keeps its configured position preset and the message box stays\r\n * content-sized (just capped by max-width so it doesn't overflow). Drag\r\n * still works everywhere because no stylesheet rule competes with the\r\n * inline position the drag handler writes.\r\n */\r\n@media (max-width: 600px) {\r\n .robot-toast-wrapper {\r\n gap: 8px;\r\n max-width: calc(100vw - 24px);\r\n }\r\n\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-bottom-right { right: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-bottom-left { left: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-top-center { top: 12px; }\r\n .robot-toast-wrapper.robot-toast-bottom-right,\r\n .robot-toast-wrapper.robot-toast-bottom-left,\r\n .robot-toast-wrapper.robot-toast-bottom-center { bottom: 12px; }\r\n\r\n .robot-toast-wrapper.robot-toast-top-center,\r\n .robot-toast-wrapper.robot-toast-bottom-center {\r\n width: calc(100vw - 24px);\r\n justify-content: center;\r\n }\r\n\r\n .robot-toast-robot {\r\n width: 48px;\r\n height: 52px;\r\n }\r\n\r\n .robot-toast-message {\r\n min-width: 100px;\r\n max-width: calc(100vw - 48px - 24px - 8px);\r\n font-size: 13px;\r\n /* padding stays 0 on the outer box; sections own their spacing */\r\n }\r\n\r\n .robot-toast-body {\r\n padding: 10px 36px 10px 12px;\r\n }\r\n\r\n .robot-toast-footer {\r\n /* Same symmetric vertical padding as body — equal section weight on mobile too */\r\n padding: 10px;\r\n }\r\n\r\n .robot-toast-text {\r\n font-size: 13px;\r\n }\r\n\r\n .robot-toast-close {\r\n width: 24px;\r\n height: 24px;\r\n font-size: 20px;\r\n }\r\n}\r\n\r\n@media (max-width: 360px) {\r\n .robot-toast-robot {\r\n width: 40px;\r\n height: 44px;\r\n }\r\n .robot-toast-message {\r\n max-width: calc(100vw - 40px - 20px - 8px);\r\n }\r\n}\r\n `;\r\n\r\n const styleElement = document.createElement('style');\r\n styleElement.id = styleId;\r\n styleElement.textContent = styles;\r\n document.head.appendChild(styleElement);\r\n }\r\n}\r\n\r\nexport default InjectStyles;\r\n","/**\r\n * RobotToast v2\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * • Multi-toast support with configurable limit + queue\r\n * • Each toast is a self-contained ToastItem instance – no shared mutable state\r\n * • Sequenced robot enter → message pop-in, message pop-out → robot exit\r\n * • Full XY drag with viewport clamping; on drop the robot snaps to the\r\n * nearest screen edge (left / right) with a personality animation\r\n * • Progress bar auto-animates for the countdown; pauses correctly on hover\r\n * and drag; resumes with exact remaining time\r\n * • All event listeners are tracked and fully removed on close\r\n * • SVG-only enforcement for custom robot images; always renders at fixed size\r\n * • SSR-safe (all DOM access is guarded by typeof window / document checks)\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n */\r\n\r\nimport type { RobotToastOptions, ToastQueueItem, ToastButton } from './types';\r\nimport InjectStyles from './styles-injector';\r\n\r\n// ─── Unique ID counter ────────────────────────────────────────────────────────\r\nlet _nextId = 1;\r\nfunction nextId(): number { return _nextId++; }\r\n\r\n// ─── Vertical offset step between stacked toasts (px) ────────────────────────\r\nconst STACK_GAP = 16;\r\n\r\n/**\r\n * Split N buttons into rows according to the layout spec:\r\n * 1→[1] 2→[2] 3→[3] 4→[2,2]\r\n * 5→[3,2] 6→[3,3] 7→[3,2,2] 8→[3,3,2] 9→[3,3,3]\r\n * 10→[3,3,2,2] 11→[3,3,3,2] 12→[3,3,3,3] …\r\n * Rule: fill rows of 3 from the top. If the tail would leave a single\r\n * lonely button, steal one from the previous row so the last two rows\r\n * balance as [2, 2].\r\n */\r\nfunction chunkButtons<T>(buttons: T[]): T[][] {\r\n const n = buttons.length;\r\n if (n === 0) return [];\r\n if (n <= 3) return [buttons.slice()];\r\n if (n === 4) return [buttons.slice(0, 2), buttons.slice(2)];\r\n\r\n const rows: T[][] = [];\r\n let i = 0;\r\n while (n - i > 4) {\r\n rows.push(buttons.slice(i, i + 3));\r\n i += 3;\r\n }\r\n const rem = n - i;\r\n if (rem === 4) {\r\n rows.push(buttons.slice(i, i + 2));\r\n rows.push(buttons.slice(i + 2));\r\n } else {\r\n rows.push(buttons.slice(i));\r\n }\r\n return rows;\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n ToastItem – one live toast on screen\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass ToastItem {\r\n readonly id: number;\r\n private options: {\r\n message: string;\r\n autoClose: boolean | number;\r\n position: NonNullable<RobotToastOptions['position']>;\r\n type: NonNullable<RobotToastOptions['type']>;\r\n theme: NonNullable<RobotToastOptions['theme']>;\r\n style?: Record<string, string | number>;\r\n typeSpeed: number;\r\n robotVariant: string;\r\n hideProgressBar: boolean;\r\n pauseOnFocusLoss: boolean;\r\n draggable: boolean;\r\n nearScreen: boolean;\r\n pauseOnHover: boolean;\r\n rtl: boolean;\r\n transition: NonNullable<RobotToastOptions['transition']>;\r\n buttons?: ToastButton[];\r\n onOpen?: () => void;\r\n onClose?: () => void;\r\n };\r\n\r\n // DOM refs\r\n private wrapper: HTMLDivElement;\r\n private robotEl: HTMLDivElement;\r\n private messageBox: HTMLDivElement;\r\n private progressBar: HTMLDivElement | null = null;\r\n private messageText: HTMLDivElement;\r\n\r\n // Timer state\r\n private autoCloseDuration: number; // ms; 0 = no auto-close\r\n private remainingTime: number; // ms left on the countdown\r\n private timerStart: number | null = null; // when the current timer was set\r\n private closeTimeout: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // Interaction state\r\n private isDragging = false;\r\n private dragOffsetX = 0;\r\n private dragOffsetY = 0;\r\n private dragWidth = 0;\r\n private dragHeight = 0;\r\n private currentRobotSide: 'left' | 'right';\r\n private isHovered = false;\r\n private isFocusLost = false;\r\n private isClosed = false;\r\n\r\n // Cleanup\r\n private cleanupFns: Array<() => void> = [];\r\n\r\n // Callback to notify the manager when this toast dies\r\n private onRemove: (id: number) => void;\r\n\r\n constructor(id: number, options: RobotToastOptions, onRemove: (id: number) => void) {\r\n this.id = id;\r\n this.onRemove = onRemove;\r\n\r\n // ── Resolve all options with defaults ──────────────────────────────────\r\n const resolved = {\r\n message: options.message,\r\n autoClose: options.autoClose ?? 5000,\r\n position: options.position ?? 'bottom-right',\r\n type: options.type ?? 'default',\r\n theme: options.theme ?? 'light',\r\n style: options.style,\r\n typeSpeed: options.typeSpeed ?? 30,\r\n robotVariant: options.robotVariant ?? '',\r\n hideProgressBar: options.hideProgressBar ?? false,\r\n pauseOnFocusLoss: options.pauseOnFocusLoss ?? true,\r\n draggable: options.draggable ?? true,\r\n nearScreen: options.nearScreen ?? true,\r\n pauseOnHover: options.pauseOnHover ?? true,\r\n rtl: options.rtl ?? false,\r\n transition: options.transition ?? 'bounce',\r\n buttons: options.buttons,\r\n onOpen: options.onOpen,\r\n onClose: options.onClose,\r\n };\r\n\r\n this.options = resolved;\r\n \r\n // Determine initial robot side based on nearScreen\r\n // nearScreen: true → robot near screen edge (position's side)\r\n // nearScreen: false → robot away from screen edge (opposite side)\r\n const positionIsLeft = resolved.position.includes('left');\r\n \r\n let initialSide: 'left' | 'right';\r\n if (resolved.nearScreen) {\r\n // Robot near edge: follow position\r\n initialSide = positionIsLeft ? 'left' : 'right';\r\n } else {\r\n // Robot away from edge: opposite of position\r\n initialSide = positionIsLeft ? 'right' : 'left';\r\n }\r\n this.currentRobotSide = initialSide;\r\n this.autoCloseDuration = typeof resolved.autoClose === 'number'\r\n ? resolved.autoClose\r\n : (resolved.autoClose ? 5000 : 0);\r\n this.remainingTime = this.autoCloseDuration;\r\n\r\n // ── Build DOM ──────────────────────────────────────────────────────────\r\n this.wrapper = this.buildWrapper();\r\n this.robotEl = this.buildRobot();\r\n this.messageBox = this.buildMessageBox();\r\n this.messageText = this.messageBox.querySelector('.robot-toast-text')!;\r\n this.progressBar = this.messageBox.querySelector('.robot-toast-progress-bar');\r\n\r\n // Empty message → hide message box entirely (only the robot shows)\r\n if (resolved.message === '') {\r\n this.messageBox.classList.add('robot-toast-empty');\r\n }\r\n\r\n this.assembleLayout();\r\n document.body.appendChild(this.wrapper);\r\n\r\n // ── Wire interactions ──────────────────────────────────────────────────\r\n if (resolved.draggable) this.initDrag();\r\n if (resolved.pauseOnFocusLoss) this.initFocusWatcher();\r\n if (resolved.pauseOnHover) this.initHoverWatcher();\r\n\r\n // ── Kick off the entrance sequence ─────────────────────────────────────\r\n requestAnimationFrame(() => this.playEntrance());\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n close(): void {\r\n if (this.isClosed) return;\r\n this.isClosed = true;\r\n\r\n this.cancelTimer();\r\n this.cleanupFns.forEach(fn => fn());\r\n this.cleanupFns = [];\r\n\r\n this.playExit(() => {\r\n if (this.wrapper.parentNode) {\r\n this.wrapper.parentNode.removeChild(this.wrapper);\r\n }\r\n this.options.onClose?.();\r\n this.onRemove(this.id);\r\n });\r\n }\r\n\r\n /** Shift this toast vertically by `delta` px (used by manager for stacking) */\r\n shiftVertical(bottomPx: number): void {\r\n const pos = this.options.position;\r\n if (pos.startsWith('bottom')) {\r\n this.wrapper.style.bottom = `${bottomPx}px`;\r\n } else {\r\n this.wrapper.style.top = `${bottomPx}px`;\r\n }\r\n }\r\n\r\n getWrapperHeight(): number {\r\n return this.wrapper.getBoundingClientRect().height || 90;\r\n }\r\n\r\n // ── DOM builders ───────────────────────────────────────────────────────────\r\n\r\n private buildWrapper(): HTMLDivElement {\r\n const w = document.createElement('div');\r\n const classes = ['robot-toast-wrapper', `robot-toast-${this.options.position}`];\r\n if (this.options.rtl) classes.push('robot-toast-rtl');\r\n w.className = classes.join(' ');\r\n\r\n // ARIA: error/warning are assertive (role=alert), everything else polite (role=status).\r\n const assertive = this.options.type === 'error' || this.options.type === 'warning';\r\n w.setAttribute('role', assertive ? 'alert' : 'status');\r\n w.setAttribute('aria-live', assertive ? 'assertive' : 'polite');\r\n w.setAttribute('aria-atomic', 'true');\r\n\r\n return w;\r\n }\r\n\r\n /**\r\n * Decides what a given `robotVariant` resolves to:\r\n * - `'hidden'` — not shown at all (omitted, '' empty, 'none' alias, or unusable string)\r\n * - `'default'` — built-in inline SVG\r\n * - `'image'` — external image source (data URL or file path)\r\n */\r\n private resolveVariant(): 'hidden' | 'default' | 'image' {\r\n const v = this.options.robotVariant;\r\n if (!v || v === 'none') return 'hidden';\r\n if (v === 'default') return 'default';\r\n const ALLOWED_EXTS = ['.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp'];\r\n const isDataUrl = v.startsWith('data:');\r\n const isAllowed = isDataUrl\r\n || ALLOWED_EXTS.some(ext => v.toLowerCase().endsWith(ext));\r\n return isAllowed ? 'image' : 'hidden';\r\n }\r\n\r\n private buildRobot(): HTMLDivElement {\r\n const r = document.createElement('div');\r\n r.className = 'robot-toast-robot';\r\n\r\n const kind = this.resolveVariant();\r\n\r\n if (kind === 'hidden') {\r\n r.style.display = 'none';\r\n return r;\r\n }\r\n\r\n if (kind === 'default') {\r\n r.innerHTML = this.getBuiltinSVG();\r\n return r;\r\n }\r\n\r\n // kind === 'image' — data URL or recognized path. Fall back to the\r\n // built-in SVG only if the image fails to load at runtime (the user\r\n // clearly intended a robot, so we don't want an empty slot).\r\n const img = document.createElement('img');\r\n img.src = this.options.robotVariant;\r\n img.alt = 'Robot';\r\n img.setAttribute('width', '65');\r\n img.setAttribute('height', '70');\r\n img.style.cssText = 'width:100%;height:100%;object-fit:contain;display:block;';\r\n img.onerror = () => { r.innerHTML = this.getBuiltinSVG(); };\r\n r.appendChild(img);\r\n return r;\r\n }\r\n\r\n private buildMessageBox(): HTMLDivElement {\r\n const box = document.createElement('div');\r\n const classes = [\r\n 'robot-toast-message',\r\n `robot-toast-type-${this.options.type}`,\r\n `robot-toast-theme-${this.options.theme}`,\r\n ].filter(Boolean);\r\n box.className = classes.join(' ');\r\n box.style.cursor = this.options.draggable ? 'grab' : 'default';\r\n\r\n // Apply inline styles if provided (takes precedence over theme colors)\r\n if (this.options.style) {\r\n Object.entries(this.options.style).forEach(([key, value]) => {\r\n const camelCaseKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (box.style as any)[camelCaseKey] = value;\r\n });\r\n }\r\n\r\n // ── Layout ────────────────────────────────────────────────────────────\r\n // Discrete sections, each owning its own spacing. The outer `box` has no\r\n // padding — bodyPad and footerPad live on the sections themselves, so\r\n // optional pieces (footer, progress bar) can appear/disappear without\r\n // us having to juggle conditional margins anywhere else.\r\n\r\n // Close button — absolute, top-right of the whole box (outside sections)\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'robot-toast-close';\r\n closeBtn.innerHTML = '×';\r\n closeBtn.title = 'Dismiss';\r\n closeBtn.type = 'button';\r\n closeBtn.setAttribute('aria-label', 'Dismiss notification');\r\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.close(); });\r\n box.appendChild(closeBtn);\r\n\r\n // Section 1 — body (message text). Always present.\r\n const body = document.createElement('div');\r\n body.className = 'robot-toast-body';\r\n const text = document.createElement('div');\r\n text.className = 'robot-toast-text';\r\n body.appendChild(text);\r\n box.appendChild(body);\r\n\r\n // Section 2 — footer (button rows). Rendered only when buttons exist.\r\n if (this.options.buttons && this.options.buttons.length > 0) {\r\n const footer = document.createElement('div');\r\n footer.className = 'robot-toast-footer';\r\n // Chunk into rows per the layout spec (1→[1] 4→[2,2] 5→[3,2] 7→[3,2,2] …)\r\n // then emit each row with `data-count` so CSS can pick the right split.\r\n const rows = chunkButtons(this.options.buttons);\r\n rows.forEach(rowBtns => {\r\n const row = document.createElement('div');\r\n row.className = 'robot-toast-row';\r\n row.setAttribute('data-count', String(rowBtns.length));\r\n rowBtns.forEach(btn => row.appendChild(this.buildButton(btn)));\r\n footer.appendChild(row);\r\n });\r\n box.appendChild(footer);\r\n }\r\n\r\n // Progress bar — unchanged, always last.\r\n const pContainer = document.createElement('div');\r\n pContainer.className = 'robot-toast-progress-container';\r\n if (this.options.hideProgressBar) pContainer.style.display = 'none';\r\n\r\n const pBar = document.createElement('div');\r\n pBar.className = 'robot-toast-progress-bar';\r\n\r\n pContainer.appendChild(pBar);\r\n box.appendChild(pContainer);\r\n\r\n return box;\r\n }\r\n\r\n private buildButton(button: ToastButton): HTMLButtonElement {\r\n const el = document.createElement('button');\r\n el.type = 'button';\r\n el.className = button.className\r\n ? `robot-toast-btn ${button.className}`\r\n : 'robot-toast-btn';\r\n el.textContent = button.label;\r\n\r\n // Inline style: same kebab → camel conversion the message-level `style`\r\n // option uses, so consumers can pass either form. Applied after className\r\n // so it takes precedence over class-based rules.\r\n if (button.style) {\r\n Object.entries(button.style).forEach(([key, value]) => {\r\n const camelKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (el.style as unknown as Record<string, string | number>)[camelKey] = value;\r\n });\r\n }\r\n\r\n el.addEventListener('click', (e) => {\r\n // Stop the click from bubbling to drag / hover handlers on the wrapper.\r\n e.stopPropagation();\r\n // Fire the callback, then dismiss. If the callback throws we still\r\n // close — otherwise a bad handler strands the toast on screen.\r\n try {\r\n button.onClick(e);\r\n } catch (err) {\r\n console.error('[robot-toast] button onClick threw:', err);\r\n }\r\n this.close();\r\n });\r\n return el;\r\n }\r\n\r\n private assembleLayout(): void {\r\n const { rtl } = this.options;\r\n this.wrapper.innerHTML = '';\r\n\r\n // Decide order: rtl flips everything, robot side controls natural order\r\n const robotOnLeft = rtl ? this.currentRobotSide === 'right' : this.currentRobotSide === 'left';\r\n\r\n if (robotOnLeft) {\r\n this.wrapper.appendChild(this.robotEl);\r\n this.wrapper.appendChild(this.messageBox);\r\n } else {\r\n this.wrapper.appendChild(this.messageBox);\r\n this.wrapper.appendChild(this.robotEl);\r\n }\r\n }\r\n\r\n // ── Sequenced animations ───────────────────────────────────────────────────\r\n\r\n private playEntrance(): void {\r\n // Step 1 – wrapper becomes visible\r\n this.wrapper.classList.add('robot-toast-visible');\r\n\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const showMessage = () => {\r\n if (messageHidden) {\r\n // No text box – skip pop-in, still fire onOpen and start timer\r\n this.options.onOpen?.();\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n // Message pops in\r\n const msgEnterClass = this.options.transition === 'bounce'\r\n ? 'message-enter'\r\n : `message-enter-${this.options.transition}`;\r\n this.messageBox.classList.add(msgEnterClass);\r\n\r\n const onMsgEntered = () => {\r\n this.messageBox.removeEventListener('animationend', onMsgEntered);\r\n this.messageBox.classList.remove(msgEnterClass);\r\n this.messageBox.style.opacity = '1';\r\n this.messageBox.style.transform = 'none';\r\n\r\n this.options.onOpen?.();\r\n this.startTyping();\r\n };\r\n this.messageBox.addEventListener('animationend', onMsgEntered, { once: true });\r\n };\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot entrance, go straight to message\r\n showMessage();\r\n } else {\r\n // Step 2 – robot runs in with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const enterClass = `robot-enter-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(enterClass);\r\n\r\n const onRobotEntered = () => {\r\n this.robotEl.removeEventListener('animationend', onRobotEntered);\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(enterClass);\r\n this.robotEl.classList.add('robot-idle');\r\n showMessage();\r\n };\r\n this.robotEl.addEventListener('animationend', onRobotEntered, { once: true });\r\n }\r\n }\r\n\r\n private playExit(done: () => void): void {\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const afterMsg = () => {\r\n this.messageBox.removeEventListener('animationend', afterMsg);\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot exit, just fade wrapper\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n } else {\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n\r\n // Step 2 – robot runs out with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const exitClass = `robot-exit-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(exitClass);\r\n\r\n const afterRobot = () => {\r\n this.robotEl.removeEventListener('animationend', afterRobot);\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n };\r\n this.robotEl.addEventListener('animationend', afterRobot, { once: true });\r\n }\r\n };\r\n\r\n if (messageHidden) {\r\n // No text box – skip the collapse step entirely\r\n afterMsg();\r\n } else {\r\n this.messageBox.classList.add('message-exit');\r\n this.messageBox.addEventListener('animationend', afterMsg, { once: true });\r\n }\r\n }\r\n\r\n // ── Typing effect ──────────────────────────────────────────────────────────\r\n\r\n private startTyping(): void {\r\n const { message, typeSpeed } = this.options;\r\n const el = this.messageText;\r\n\r\n if (typeSpeed === 0) {\r\n // Instant – no animation\r\n el.textContent = message;\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n\r\n let index = 0;\r\n let active = true;\r\n\r\n // Register cleanup so that if toast is closed mid-type the loop stops\r\n this.cleanupFns.push(() => { active = false; });\r\n\r\n const tick = () => {\r\n if (!active) return;\r\n if (index < message.length) {\r\n el.textContent += message.charAt(index++);\r\n setTimeout(tick, typeSpeed);\r\n } else {\r\n this.afterTypingComplete();\r\n }\r\n };\r\n tick();\r\n }\r\n\r\n private afterTypingComplete(): void {\r\n // Always start auto-progress-bar animation (unless hidden)\r\n if (this.autoCloseDuration > 0 && !this.options.hideProgressBar && this.progressBar) {\r\n this.progressBar.style.animationDuration = `${this.autoCloseDuration}ms`; // set duration FIRST\r\n void this.progressBar.offsetWidth; // flush\r\n this.progressBar.classList.add('robot-toast-progress-auto'); // THEN start\r\n if (this.isHovered || this.isFocusLost) {\r\n this.progressBar.classList.add('robot-toast-progress-paused');\r\n }\r\n }\r\n\r\n // Start the close timer unless something is currently pausing it\r\n if (!this.isHovered && !this.isFocusLost) {\r\n this.startTimer();\r\n }\r\n }\r\n\r\n // ── Timer management ───────────────────────────────────────────────────────\r\n\r\n private startTimer(): void {\r\n if (this.autoCloseDuration <= 0 || this.remainingTime <= 0) return;\r\n this.timerStart = Date.now();\r\n this.closeTimeout = setTimeout(() => this.close(), this.remainingTime);\r\n }\r\n\r\n private pauseTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n if (this.timerStart !== null) {\r\n const elapsed = Date.now() - this.timerStart;\r\n this.remainingTime = Math.max(0, this.remainingTime - elapsed);\r\n this.timerStart = null;\r\n }\r\n }\r\n this.progressBar?.classList.add('robot-toast-progress-paused');\r\n }\r\n\r\n private resumeTimer(): void {\r\n if (this.isHovered || this.isFocusLost || this.isDragging) return;\r\n this.progressBar?.classList.remove('robot-toast-progress-paused');\r\n this.startTimer();\r\n }\r\n\r\n private cancelTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n }\r\n }\r\n\r\n // ── Hover watcher ──────────────────────────────────────────────────────────\r\n\r\n private initHoverWatcher(): void {\r\n const onEnter = () => {\r\n this.isHovered = true;\r\n this.pauseTimer();\r\n };\r\n const onLeave = () => {\r\n this.isHovered = false;\r\n this.resumeTimer();\r\n };\r\n this.wrapper.addEventListener('mouseenter', onEnter);\r\n this.wrapper.addEventListener('mouseleave', onLeave);\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('mouseenter', onEnter);\r\n this.wrapper.removeEventListener('mouseleave', onLeave);\r\n });\r\n }\r\n\r\n // ── Focus watcher ──────────────────────────────────────────────────────────\r\n\r\n private initFocusWatcher(): void {\r\n const onBlur = () => {\r\n this.isFocusLost = true;\r\n this.pauseTimer();\r\n };\r\n const onFocus = () => {\r\n this.isFocusLost = false;\r\n this.resumeTimer();\r\n };\r\n window.addEventListener('blur', onBlur);\r\n window.addEventListener('focus', onFocus);\r\n this.cleanupFns.push(() => {\r\n window.removeEventListener('blur', onBlur);\r\n window.removeEventListener('focus', onFocus);\r\n });\r\n }\r\n\r\n // ── Drag ──────────────────────────────────────────────────────────────────\r\n\r\n private initDrag(): void {\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Pointer events (covers both mouse & touch via pointer API) ──────────\r\n const onPointerDown = (e: PointerEvent) => {\r\n // Clicks / taps on the close button or any inline action button must\r\n // never initiate a drag — otherwise the user can't actually press them.\r\n if ((e.target as HTMLElement).closest(\r\n '.robot-toast-close, .robot-toast-btn'\r\n )) return;\r\n // Only primary button / first touch\r\n if (e.button !== undefined && e.button !== 0) return;\r\n\r\n e.preventDefault();\r\n this.isDragging = true;\r\n this.pauseTimer();\r\n\r\n // \"Detach\" the wrapper from its CSS-positioned slot by converting its\r\n // current visual position into explicit inline top/left values.\r\n const rect = this.wrapper.getBoundingClientRect();\r\n this.wrapper.classList.add('robot-toast-dragging');\r\n\r\n // Inline position so the wrapper sits exactly where it was\r\n this.wrapper.style.top = `${rect.top}px`;\r\n this.wrapper.style.left = `${rect.left}px`;\r\n this.wrapper.style.right = 'auto';\r\n this.wrapper.style.bottom = 'auto';\r\n this.wrapper.style.transform = 'none';\r\n\r\n // Cache size — width/height don't change during drag, so we avoid a\r\n // layout read on every pointermove (major mobile jank source).\r\n this.dragWidth = rect.width;\r\n this.dragHeight = rect.height;\r\n\r\n // Offset = where inside the wrapper the pointer grabbed\r\n this.dragOffsetX = e.clientX - rect.left;\r\n this.dragOffsetY = e.clientY - rect.top;\r\n\r\n this.messageBox.style.cursor = 'grabbing';\r\n this.wrapper.setPointerCapture(e.pointerId);\r\n };\r\n\r\n const onPointerMove = (e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n e.preventDefault();\r\n\r\n // Use cached width/height + live window dims — no layout flush.\r\n const maxX = window.innerWidth - this.dragWidth;\r\n const maxY = window.innerHeight - this.dragHeight;\r\n\r\n const newLeft = Math.max(0, Math.min(e.clientX - this.dragOffsetX, maxX));\r\n const newTop = Math.max(0, Math.min(e.clientY - this.dragOffsetY, maxY));\r\n\r\n this.wrapper.style.left = `${newLeft}px`;\r\n this.wrapper.style.top = `${newTop}px`;\r\n };\r\n\r\n const onPointerUp = (_e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n this.isDragging = false;\r\n this.wrapper.classList.remove('robot-toast-dragging');\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Snap to nearest horizontal screen edge ────────────────────────────\r\n // One getBoundingClientRect() on drop is fine — it's a single layout\r\n // flush per release, not per frame. This is more robust than reading\r\n // inline style.left, which can lag the rendered position in edge cases\r\n // (parent transforms, pending animations, etc.).\r\n const rect = this.wrapper.getBoundingClientRect();\r\n const currentTop = rect.top;\r\n const midX = rect.left + rect.width / 2;\r\n const centerX = window.innerWidth / 2;\r\n\r\n // Determine which edge to snap to based on which half the center is in\r\n const snapToLeft = midX < centerX;\r\n\r\n // Determine robot side based on nearScreen setting\r\n const newRobotSide: 'left' | 'right' = this.options.nearScreen\r\n ? (snapToLeft ? 'left' : 'right')\r\n : (snapToLeft ? 'right' : 'left');\r\n\r\n // Determine final resting left position (20px margin from edge)\r\n const finalLeft = snapToLeft ? 20 : window.innerWidth - this.dragWidth - 20;\r\n const finalTop = Math.max(20, Math.min(currentTop, window.innerHeight - this.dragHeight - 20));\r\n\r\n // Re-enable transitions for the snap glide\r\n this.wrapper.style.transition =\r\n 'left 0.45s cubic-bezier(0.34,1.56,0.64,1), top 0.4s cubic-bezier(0.34,1.56,0.64,1)';\r\n this.wrapper.style.left = `${finalLeft}px`;\r\n this.wrapper.style.top = `${finalTop}px`;\r\n\r\n // Update robot side if it changed\r\n if (newRobotSide !== this.currentRobotSide) {\r\n this.currentRobotSide = newRobotSide;\r\n\r\n // Use CSS order to visually reorder (no DOM detach = no animation restart)\r\n const robotOnLeft = newRobotSide === 'left';\r\n this.robotEl.style.order = robotOnLeft ? '0' : '1';\r\n this.messageBox.style.order = robotOnLeft ? '1' : '0';\r\n\r\n // Snap animation\r\n const snapClass = newRobotSide === 'left' ? 'robot-snap-left' : 'robot-snap-right';\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n this.robotEl.classList.add(snapClass);\r\n this.robotEl.addEventListener('animationend', () => {\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(snapClass);\r\n this.robotEl.classList.add('robot-idle');\r\n }, { once: true });\r\n }\r\n const clearTransition = () => {\r\n this.wrapper.style.transition = '';\r\n };\r\n setTimeout(clearTransition, 500);\r\n\r\n // Resume the auto-close timer\r\n this.resumeTimer();\r\n };\r\n\r\n this.wrapper.addEventListener('pointerdown', onPointerDown);\r\n this.wrapper.addEventListener('pointermove', onPointerMove);\r\n this.wrapper.addEventListener('pointerup', onPointerUp);\r\n this.wrapper.addEventListener('pointercancel', onPointerUp);\r\n\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('pointerdown', onPointerDown);\r\n this.wrapper.removeEventListener('pointermove', onPointerMove);\r\n this.wrapper.removeEventListener('pointerup', onPointerUp);\r\n this.wrapper.removeEventListener('pointercancel', onPointerUp);\r\n });\r\n }\r\n\r\n // ── Built-in robot SVG ─────────────────────────────────────────────────────\r\n\r\n private getBuiltinSVG(): string {\r\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 120\"\r\n width=\"100%\" height=\"100%\" role=\"img\" aria-label=\"Robot\">\r\n <defs>\r\n <linearGradient id=\"rtGrad${this.id}\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#E2F0FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#B8D8FF\"/>\r\n </linearGradient>\r\n <linearGradient id=\"rtAccent${this.id}\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#7CB9FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#4A90D9\"/>\r\n </linearGradient>\r\n </defs>\r\n <!-- Antenna -->\r\n <line x1=\"50\" y1=\"4\" x2=\"50\" y2=\"18\" stroke=\"#2B3A55\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\r\n <circle cx=\"50\" cy=\"4\" r=\"4\" fill=\"#FF6B6B\"/>\r\n <!-- Head -->\r\n <rect x=\"24\" y=\"18\" width=\"52\" height=\"40\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Eyes -->\r\n <circle cx=\"38\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"62\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"40\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <circle cx=\"64\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <!-- Mouth -->\r\n <path d=\"M 38 50 Q 50 58 62 50\" stroke=\"#2B3A55\" stroke-width=\"2\"\r\n fill=\"none\" stroke-linecap=\"round\"/>\r\n <!-- Neck -->\r\n <rect x=\"44\" y=\"58\" width=\"12\" height=\"8\" rx=\"3\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <!-- Body -->\r\n <rect x=\"22\" y=\"66\" width=\"56\" height=\"44\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Chest panel -->\r\n <rect x=\"34\" y=\"76\" width=\"32\" height=\"20\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <circle cx=\"42\" cy=\"86\" r=\"3\" fill=\"#FF6B6B\"/>\r\n <circle cx=\"50\" cy=\"86\" r=\"3\" fill=\"#FFD700\"/>\r\n <circle cx=\"58\" cy=\"86\" r=\"3\" fill=\"#6BFF8A\"/>\r\n <!-- Arms -->\r\n <rect x=\"4\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <rect x=\"78\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Legs -->\r\n <rect x=\"30\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <rect x=\"54\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n </svg>`;\r\n }\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n RobotToastManager – global singleton that owns all ToastItems\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass RobotToastManager {\r\n private static _instance: RobotToastManager | null = null;\r\n\r\n private activeToasts: ToastItem[] = [];\r\n private queue: ToastQueueItem[] = [];\r\n private globalLimit = 0; // 0 = unlimited; overridden per-show call\r\n\r\n private constructor() {\r\n new InjectStyles();\r\n }\r\n\r\n static getInstance(): RobotToastManager {\r\n if (!RobotToastManager._instance) {\r\n RobotToastManager._instance = new RobotToastManager();\r\n }\r\n return RobotToastManager._instance;\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n show(options: RobotToastOptions): number {\r\n if (typeof document === 'undefined') return -1;\r\n\r\n const id = nextId();\r\n const limit = options.limit ?? this.globalLimit;\r\n\r\n if (limit > 0 && this.activeToasts.length >= limit) {\r\n // Queue it for later\r\n this.queue.push({ options, id });\r\n return id;\r\n }\r\n\r\n this.spawnToast(options, id);\r\n return id;\r\n }\r\n\r\n closeAll(): void {\r\n this.queue = [];\r\n [...this.activeToasts].forEach(t => t.close());\r\n }\r\n\r\n closeById(id: number): void {\r\n const toast = this.activeToasts.find(t => t.id === id);\r\n if (toast) toast.close();\r\n\r\n // Also remove from queue if it hasn't spawned yet\r\n this.queue = this.queue.filter(q => q.id !== id);\r\n }\r\n\r\n // ── Internal ───────────────────────────────────────────────────────────────\r\n\r\n private spawnToast(options: RobotToastOptions, id: number): void {\r\n const toast = new ToastItem(id, options, (doneId) => this.handleRemoved(doneId));\r\n const newestOnTop = options.newestOnTop ?? false;\r\n\r\n if (newestOnTop) {\r\n this.activeToasts.unshift(toast);\r\n } else {\r\n this.activeToasts.push(toast);\r\n }\r\n\r\n this.restack();\r\n }\r\n\r\n private handleRemoved(id: number): void {\r\n this.activeToasts = this.activeToasts.filter(t => t.id !== id);\r\n this.restack();\r\n\r\n // Dequeue next if any\r\n if (this.queue.length > 0) {\r\n const next = this.queue.shift()!;\r\n // Small delay so the stack reflows are visible\r\n setTimeout(() => this.spawnToast(next.options, next.id), 120);\r\n }\r\n }\r\n\r\n /**\r\n * Recalculate the vertical position of every active toast so they stack\r\n * neatly without overlap. Works for both top-* and bottom-* positions.\r\n */\r\n private restack(): void {\r\n // Group by position string\r\n const groups: Record<string, ToastItem[]> = {};\r\n this.activeToasts.forEach(t => {\r\n const pos = (t as any).options.position as string;\r\n if (!groups[pos]) groups[pos] = [];\r\n groups[pos].push(t);\r\n });\r\n\r\n Object.keys(groups).forEach(pos => {\r\n const list = groups[pos];\r\n let offset = 20; // initial edge margin px\r\n\r\n list.forEach((toast) => {\r\n toast.shiftVertical(offset);\r\n offset += toast.getWrapperHeight() + STACK_GAP;\r\n });\r\n });\r\n }\r\n}\r\n\r\nexport { RobotToastManager as default, RobotToastManager };","/**\r\n * RobotToast Utilities v2\r\n * Helper functions for safer access to the RobotToast API.\r\n * Handles async readiness checks, SSR guards, and error boundaries.\r\n * Useful when loading robot-toast via a CDN <script> tag.\r\n */\r\n\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\n\r\n/**\r\n * Wait for window.RobotToast to be available, up to `timeout` ms.\r\n * Resolves immediately if it is already loaded.\r\n * Useful when the library is loaded via a <script> tag and you need\r\n * to call it from another script that may execute first.\r\n */\r\nexport function ensureRobotToastReady(timeout = 5000): Promise<RobotToastAPI> {\r\n return new Promise((resolve, reject) => {\r\n if (typeof window === 'undefined') {\r\n reject(new Error('[RobotToast] Cannot run outside of a browser environment.'));\r\n return;\r\n }\r\n\r\n if (window.RobotToast) {\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n const interval = setInterval(() => {\r\n if (window.RobotToast) {\r\n clearInterval(interval);\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n if (Date.now() - startTime >= timeout) {\r\n clearInterval(interval);\r\n reject(new Error(`[RobotToast] Failed to load within ${timeout}ms.`));\r\n }\r\n }, 80);\r\n });\r\n}\r\n\r\n/**\r\n * Show a robot toast notification.\r\n * Waits for the library to be ready before showing.\r\n * Returns the toast id or -1 on failure.\r\n */\r\nexport async function showRobotToast(options: RobotToastOptions): Promise<number> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n return api.show(options);\r\n } catch (err) {\r\n console.error('[RobotToast] showRobotToast failed:', err);\r\n return -1;\r\n }\r\n}\r\n\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\nexport async function closeAllRobotToasts(): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeAll();\r\n } catch (err) {\r\n console.error('[RobotToast] closeAllRobotToasts failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Close a specific toast by the id returned from show().\r\n */\r\nexport async function closeRobotToastById(id: number): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeById(id);\r\n } catch (err) {\r\n console.error('[RobotToast] closeRobotToastById failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Get the RobotToast API instance.\r\n */\r\nexport async function getRobotToastInstance(): Promise<RobotToastAPI> {\r\n return ensureRobotToastReady();\r\n}","/**\r\n * RobotToast Types & Constants\r\n * Type definitions and constant arrays for the robot toast notification library\r\n */\r\n\r\n/** Array of all valid toast positions */\r\nexport const TOAST_POSITIONS = [\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] as const;\r\n\r\n/** Array of all valid toast types */\r\nexport const TOAST_TYPES = ['default', 'info', 'success', 'warning', 'error'] as const;\r\n\r\n/** Array of all valid toast themes */\r\nexport const TOAST_THEMES = ['light', 'dark', 'colored'] as const;\r\n\r\n/** Array of all valid transition animations */\r\nexport const TOAST_TRANSITIONS = ['bounce', 'slide', 'zoom', 'flip'] as const;\r\n\r\n/** Type derived from TOAST_POSITIONS constant */\r\nexport type ToastPosition = typeof TOAST_POSITIONS[number];\r\n\r\n/** Type derived from TOAST_TYPES constant */\r\nexport type ToastType = typeof TOAST_TYPES[number];\r\n\r\n/** Type derived from TOAST_THEMES constant */\r\nexport type ToastTheme = typeof TOAST_THEMES[number];\r\n\r\n/** Type derived from TOAST_TRANSITIONS constant */\r\nexport type TransitionType = typeof TOAST_TRANSITIONS[number];\r\n\r\n/**\r\n * A button rendered inside the toast. Pass an array of these as `buttons`\r\n * to add inline CTAs like \"Undo\" / \"Retry\" / \"Cancel\":\r\n *\r\n * toast({\r\n * message: 'File deleted',\r\n * buttons: [\r\n * { label: 'Undo', onClick: () => restore() },\r\n * ],\r\n * });\r\n *\r\n * Buttons render in array order. Clicking any of them fires its `onClick`\r\n * and then closes the toast. Visual hierarchy is up to you — pass a custom\r\n * `className` to override the default neutral style (e.g. to mark the\r\n * primary CTA as filled/bold and a secondary as muted).\r\n */\r\nexport interface ToastButton {\r\n /** Visible button text. Keep it short (1–2 words). */\r\n label: string;\r\n /** Fired before the toast closes. Receives the click event. */\r\n onClick: (event: MouseEvent) => void;\r\n /**\r\n * Optional CSS class(es) appended to the button element. Use this when you\r\n * have a stylesheet rule like `.my-primary { background: black; color: white }`\r\n * defined elsewhere in your app and want to apply it to this button.\r\n */\r\n className?: string;\r\n /**\r\n * Optional inline styles applied directly to the button element. Use this\r\n * when you don't want to add a CSS rule to your stylesheet — pass an object\r\n * of camelCased properties (or kebab-case keys; both work):\r\n *\r\n * style: { background: 'black', color: 'white', borderRadius: '8px' }\r\n *\r\n * Takes precedence over className-based rules and over the default neutral\r\n * (and solo-CTA) button styles.\r\n */\r\n style?: Record<string, string | number>;\r\n}\r\n\r\nexport interface RobotToastOptions {\r\n /** The message text to display in the toast */\r\n message: string;\r\n\r\n /** Auto-close duration in ms, or false to disable. Default: 5000 */\r\n autoClose?: boolean | number;\r\n\r\n /** Position of the toast on screen. Default: 'bottom-right' */\r\n position?: ToastPosition;\r\n\r\n /** Toast type/style. Default: 'default' */\r\n type?: ToastType;\r\n\r\n /** Visual theme. Default: 'light' */\r\n theme?: ToastTheme;\r\n\r\n /**\r\n * Inline style object to apply directly to the message box element.\r\n * This allows runtime customization of colors, fonts, backgrounds, etc.\r\n * Example: { color: 'red', backgroundColor: 'blue' }\r\n * This takes precedence over className for conflicting properties.\r\n */\r\n style?: Record<string, string | number>;\r\n\r\n /** Typing speed in ms per character. 0 = instant. Default: 30 */\r\n typeSpeed?: number;\r\n\r\n /**\r\n * Robot image source. Opt-in — nothing is shown unless you ask for one.\r\n * Pass one of:\r\n * - Omit (or pass `undefined` / `''` / `'none'`) to hide the robot entirely.\r\n * - `'default'` to render the built-in inline SVG (no network fetch).\r\n * - A data URL from `robot-toast/robots` (tree-shakeable, recommended):\r\n * import { wave } from 'robot-toast/robots';\r\n * toast({ message: 'Hi', robotVariant: wave });\r\n * - A path to an image file (svg/png/jpg/jpeg/gif/webp).\r\n * Unrecognized values are treated as \"hidden\" rather than rendered.\r\n */\r\n robotVariant?: string;\r\n\r\n /** Hide the countdown progress bar. Default: false */\r\n hideProgressBar?: boolean;\r\n\r\n /** Pause the auto-close countdown when the window loses focus. Default: true */\r\n pauseOnFocusLoss?: boolean;\r\n\r\n /** Allow the user to drag the toast around the screen. Default: true */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Position the robot near the screen edge (true) or away from it (false).\r\n * - true: robot appears between screen edge and message bubble\r\n * - false: message bubble appears between screen edge and robot\r\n * The position is automatically determined by the toast position and this setting.\r\n * Default: true\r\n */\r\n nearScreen?: boolean;\r\n\r\n /** Pause the auto-close countdown while the cursor is over the toast. Default: true */\r\n pauseOnHover?: boolean;\r\n\r\n /**\r\n * Maximum number of toasts visible simultaneously.\r\n * Excess toasts are queued and shown as soon as a slot opens.\r\n * 0 = unlimited (queue still works, all show in parallel). Default: 0\r\n */\r\n limit?: number;\r\n\r\n /** Stack newest toasts on top of older ones. Default: false */\r\n newestOnTop?: boolean;\r\n\r\n /** Right-to-left layout (message on the right, robot on the left). Default: false */\r\n rtl?: boolean;\r\n\r\n /** Entry / exit transition style. Default: 'bounce' */\r\n transition?: TransitionType;\r\n\r\n /**\r\n * Inline buttons to render inside the toast (e.g. Undo, Retry, Cancel).\r\n * Rendered in array order. Each click fires the button's `onClick` and\r\n * then closes the toast automatically.\r\n */\r\n buttons?: ToastButton[];\r\n\r\n /** Called when the toast finishes its enter animation and is fully visible. */\r\n onOpen?: () => void;\r\n\r\n /** Called after the toast has fully exited the screen. */\r\n onClose?: () => void;\r\n}\r\n\r\n/** Internal representation of a queued toast item */\r\nexport interface ToastQueueItem {\r\n options: RobotToastOptions;\r\n id: number;\r\n}\r\n\r\nexport interface RobotToastAPI {\r\n /** Show a toast notification – queued automatically when limit is reached */\r\n show: (options: RobotToastOptions) => number;\r\n /** Immediately close all visible toasts and clear the queue */\r\n closeAll: () => void;\r\n /** Close a specific toast by the id returned from show() */\r\n closeById: (id: number) => void;\r\n /** Get the RobotToastManager instance */\r\n getInstance: () => RobotToastInstance;\r\n}\r\n\r\nexport interface RobotToastInstance {\r\n show: (options: RobotToastOptions) => number;\r\n closeAll: () => void;\r\n closeById: (id: number) => void;\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n __robotToastLoaded?: boolean;\r\n __robotToastUtilsLoaded?: boolean;\r\n RobotToast?: RobotToastAPI;\r\n RobotToastUtils?: {\r\n showRobotToast: (options: RobotToastOptions) => Promise<number>;\r\n closeAllRobotToasts: () => Promise<void>;\r\n closeRobotToastById: (id: number) => Promise<void>;\r\n getRobotToastInstance: () => Promise<RobotToastAPI>;\r\n ensureRobotToastReady: (timeout?: number) => Promise<RobotToastAPI>;\r\n };\r\n }\r\n}","/**\r\n * robot-toast v2\r\n * A lightweight, framework-agnostic toast notification library\r\n * with an animated robot character, multi-toast queue, and smooth drag.\r\n *\r\n * ── Basic usage ──────────────────────────────────────────────────────────────\r\n * import { toast } from 'robot-toast';\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', position: 'top-right', type: 'success' });\r\n *\r\n * ── Typed shorthands ─────────────────────────────────────────────────────────\r\n * toast.success('Saved!');\r\n * toast.error('Something went wrong');\r\n * toast.info('Did you know…');\r\n * toast.warning('Check your input');\r\n *\r\n * ── Class / manager ──────────────────────────────────────────────────────────\r\n * import { RobotToast } from 'robot-toast';\r\n * const manager = RobotToast.getInstance();\r\n * const id = manager.show({ message: 'Hi!' });\r\n * manager.closeById(id);\r\n */\r\n\r\nimport RobotToastManager from './toast';\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\nimport './styles-injector'; // Auto-inject styles\r\n\r\n// ─── Core show function ────────────────────────────────────────────────────\r\n\r\ntype ToastInput = string | RobotToastOptions;\r\n\r\nfunction normalise(input: ToastInput): RobotToastOptions {\r\n return typeof input === 'string' ? { message: input } : input;\r\n}\r\n\r\n/**\r\n * Show a toast notification.\r\n * Accepts either a plain string or a full options object.\r\n * Returns the toast id (useful for closeById).\r\n *\r\n * @example\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', type: 'success', position: 'top-right' });\r\n */\r\nfunction toast(input: ToastInput): number {\r\n if (typeof window === 'undefined') return -1;\r\n return RobotToastManager.getInstance().show(normalise(input));\r\n}\r\n\r\n// ── Typed shorthand helpers ───────────────────────────────────────────────────\r\ntoast.success = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'success' });\r\n\r\ntoast.error = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'error' });\r\n\r\ntoast.info = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'info' });\r\n\r\ntoast.warning = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'warning' });\r\n\r\n// ── Close helpers ─────────────────────────────────────────────────────────────\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\ntoast.closeAll = (): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeAll();\r\n};\r\n\r\n/**\r\n * Close a specific toast by the id returned from toast() / toast.show().\r\n */\r\ntoast.closeById = (id: number): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeById(id);\r\n};\r\n\r\n// ── Promise helper ────────────────────────────────────────────────────────────\r\n\r\ntype PromiseMessage<T, E = unknown> = {\r\n loading: string | Partial<RobotToastOptions>;\r\n success: string | ((value: T) => string | Partial<RobotToastOptions>);\r\n error: string | ((err: E) => string | Partial<RobotToastOptions>);\r\n};\r\n\r\n/**\r\n * Attach a toast lifecycle to a promise.\r\n * Shows a persistent `loading` toast; on settlement, closes it and shows a\r\n * `success` or `error` toast. Returns the original promise unchanged so\r\n * callers can still await / chain it.\r\n *\r\n * @example\r\n * toast.promise(fetch('/api/save'), {\r\n * loading: 'Saving…',\r\n * success: 'Saved!',\r\n * error: 'Save failed',\r\n * });\r\n */\r\ntoast.promise = <T, E = unknown>(\r\n promise: Promise<T>,\r\n messages: PromiseMessage<T, E>,\r\n): Promise<T> => {\r\n if (typeof window === 'undefined') return promise;\r\n\r\n const loadingOpts: RobotToastOptions =\r\n typeof messages.loading === 'string'\r\n ? { message: messages.loading }\r\n : { message: '', ...messages.loading };\r\n\r\n const loadingId = toast({\r\n autoClose: false,\r\n hideProgressBar: true,\r\n ...loadingOpts,\r\n // Override typeSpeed for loading so the text appears immediately — a loading\r\n // state that types letter-by-letter feels wrong.\r\n typeSpeed: loadingOpts.typeSpeed ?? 0,\r\n });\r\n\r\n const resolveOptions = (\r\n v: string | Partial<RobotToastOptions>,\r\n fallbackType: RobotToastOptions['type'],\r\n ): RobotToastOptions => {\r\n const base = typeof v === 'string' ? { message: v } : { message: '', ...v };\r\n return { type: fallbackType, ...base };\r\n };\r\n\r\n return promise.then(\r\n (value) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.success === 'function'\r\n ? messages.success(value)\r\n : messages.success;\r\n toast(resolveOptions(next, 'success'));\r\n return value;\r\n },\r\n (err: E) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.error === 'function'\r\n ? messages.error(err)\r\n : messages.error;\r\n toast(resolveOptions(next, 'error'));\r\n throw err;\r\n },\r\n );\r\n};\r\n\r\nexport { toast };\r\n\r\n// ─── Class export ──────────────────────────────────────────────────────────\r\n\r\nexport { default as RobotToast, RobotToastManager } from './toast';\r\n\r\n// ─── Utilities ─────────────────────────────────────────────────────────────\r\n\r\nexport {\r\n ensureRobotToastReady,\r\n showRobotToast,\r\n closeAllRobotToasts,\r\n getRobotToastInstance,\r\n} from './utils';\r\n\r\n// ─── Types ─────────────────────────────────────────────────────────────────\r\n\r\nexport type {\r\n RobotToastOptions,\r\n RobotToastAPI,\r\n RobotToastInstance,\r\n ToastQueueItem,\r\n ToastPosition,\r\n ToastType,\r\n ToastTheme,\r\n TransitionType,\r\n} from './types';\r\n\r\nexport {\r\n TOAST_POSITIONS,\r\n TOAST_TYPES,\r\n TOAST_THEMES,\r\n TOAST_TRANSITIONS,\r\n} from './types';\r\n\r\n// ─── Global registration (for script-tag / CDN usage) ──────────────────────\r\n\r\nfunction registerGlobal(): void {\r\n if (typeof window === 'undefined') return;\r\n if (window.__robotToastLoaded) return;\r\n window.__robotToastLoaded = true;\r\n\r\n const api: RobotToastAPI = {\r\n show: (options: RobotToastOptions) => RobotToastManager.getInstance().show(options),\r\n closeAll: () => RobotToastManager.getInstance().closeAll(),\r\n closeById: (id: number) => RobotToastManager.getInstance().closeById(id),\r\n getInstance: () => RobotToastManager.getInstance(),\r\n };\r\n\r\n window.RobotToast = api;\r\n}\r\n\r\nregisterGlobal();"]}
|
package/dist/index.mjs
CHANGED
|
@@ -241,6 +241,8 @@ var f=class f{constructor(){typeof document>"u"||f.injected||(f.injected=true,th
|
|
|
241
241
|
background: none;
|
|
242
242
|
border: none;
|
|
243
243
|
font-size: 24px;
|
|
244
|
+
line-height: 1;
|
|
245
|
+
font-family: Arial, sans-serif;
|
|
244
246
|
cursor: pointer;
|
|
245
247
|
opacity: 0.6;
|
|
246
248
|
transition: opacity 0.2s;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/styles-injector.ts","../src/toast.ts","../src/utils.ts","../src/types.ts","../src/index.ts"],"names":["_InjectStyles","styleId","styles","styleElement","InjectStyles","styles_injector_default","_nextId","nextId","STACK_GAP","chunkButtons","buttons","n","rows","i","ToastItem","id","options","onRemove","resolved","positionIsLeft","initialSide","fn","bottomPx","w","classes","assertive","v","ALLOWED_EXTS","ext","r","kind","img","box","key","value","camelCaseKey","g","closeBtn","e","body","text","footer","rowBtns","row","btn","pContainer","pBar","button","el","camelKey","err","rtl","robotHidden","messageHidden","showMessage","msgEnterClass","onMsgEntered","side","transitionSuffix","enterClass","onRobotEntered","done","afterMsg","exitClass","afterRobot","message","typeSpeed","index","active","tick","elapsed","onEnter","onLeave","onBlur","onFocus","onPointerDown","rect","onPointerMove","maxX","maxY","newLeft","newTop","onPointerUp","_e","currentTop","midX","centerX","snapToLeft","newRobotSide","finalLeft","finalTop","robotOnLeft","snapClass","_RobotToastManager","limit","toast","t","q","doneId","next","groups","pos","list","offset","RobotToastManager","ensureRobotToastReady","timeout","resolve","reject","startTime","interval","showRobotToast","closeAllRobotToasts","getRobotToastInstance","TOAST_POSITIONS","TOAST_TYPES","TOAST_THEMES","TOAST_TRANSITIONS","normalise","input","promise","messages","loadingOpts","loadingId","resolveOptions","fallbackType","base","registerGlobal","api"],"mappings":"AAKA,IAAMA,CAAAA,CAAN,MAAMA,CAAa,CAGjB,WAAA,EAAc,CACR,OAAO,QAAA,CAAa,GAAA,EAAeA,CAAAA,CAAa,QAAA,GAIpDA,CAAAA,CAAa,SAAW,IAAA,CACxB,IAAA,CAAK,SAAA,EAAU,EACjB,CAEQ,SAAA,EAAkB,CACxB,IAAMC,CAAAA,CAAU,oBAAA,CAGhB,GAAI,QAAA,CAAS,cAAA,CAAeA,CAAO,CAAA,CACjC,OAGF,IAAMC,CAAAA,CAAS;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CAgvBTC,CAAAA,CAAe,QAAA,CAAS,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","file":"index.mjs","sourcesContent":["/**\r\n * Style injection for RobotToast\r\n * Injects all required CSS into the document when instantiated\r\n */\r\n\r\nclass InjectStyles {\r\n private static injected = false;\r\n\r\n constructor() {\r\n if (typeof document === 'undefined' || InjectStyles.injected) {\r\n return;\r\n }\r\n\r\n InjectStyles.injected = true;\r\n this.injectCSS();\r\n }\r\n\r\n private injectCSS(): void {\r\n const styleId = 'robot-toast-styles';\r\n\r\n // Check if styles already exist\r\n if (document.getElementById(styleId)) {\r\n return;\r\n }\r\n\r\n const styles = `\r\n/* RobotToast v2 - CSS Styles */\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* WRAPPER - Fixed positioning container for each toast */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-wrapper {\r\n position: fixed;\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n opacity: 0;\r\n z-index: 99999;\r\n pointer-events: auto;\r\n touch-action: none;\r\n -webkit-user-select: none;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-visible {\r\n opacity: 1;\r\n}\r\n\r\n/* Position presets */\r\n.robot-toast-wrapper.robot-toast-top-right {\r\n top: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-left {\r\n top: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-center {\r\n top: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-right {\r\n bottom: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-left {\r\n bottom: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-center {\r\n bottom: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-rtl {\r\n direction: rtl;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-dragging .robot-toast-message {\r\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ROBOT - The animated character */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-robot {\r\n width: 65px;\r\n height: 70px;\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0;\r\n}\r\n\r\n.robot-toast-robot img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-left {\r\n animation: robot-enter-left 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right {\r\n animation: robot-enter-right 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left {\r\n animation: robot-exit-left 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right {\r\n animation: robot-exit-right 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-idle {\r\n opacity: 1;\r\n animation: robot-idle 2s ease-in-out infinite;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-left {\r\n animation: robot-snap-left 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-right {\r\n animation: robot-snap-right 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* MESSAGE BOX - Toast content container */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-message {\r\n position: relative;\r\n width: fit-content;\r\n min-width: 120px;\r\n max-width: min(400px, calc(100vw - 120px));\r\n /*\r\n * IMPORTANT: no padding on the outer box. Each section (.robot-toast-body,\r\n * .robot-toast-footer, .robot-toast-progress-container) owns its own\r\n * spacing, so optional sections can disappear without us having to tweak\r\n * margins / paddings anywhere else.\r\n */\r\n padding: 0;\r\n border-radius: 8px;\r\n margin: 0;\r\n opacity: 0;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\r\n user-select: none;\r\n cursor: default;\r\n box-sizing: border-box;\r\n}\r\n\r\n.robot-toast-message.robot-toast-empty {\r\n display: none;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light {\r\n background: #ffffff;\r\n color: #333333;\r\n border: 1px solid #e0e0e0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark {\r\n background: #2d2d2d;\r\n color: #f0f0f0;\r\n border: 1px solid #444444;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored {\r\n color: #ffffff;\r\n}\r\n\r\n/* Type-specific colors for colored theme */\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-default {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-info {\r\n background: linear-gradient(135deg, #2193b0 0%, #6dd5ed 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-success {\r\n background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-warning {\r\n background: linear-gradient(135deg, #fb6e3b 0%, #f5a623 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-error {\r\n background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);\r\n}\r\n\r\n/* Light theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-info {\r\n border-left: 4px solid #2193b0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-success {\r\n border-left: 4px solid #11998e;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-warning {\r\n border-left: 4px solid #fb6e3b;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-error {\r\n border-left: 4px solid #eb3349;\r\n}\r\n\r\n/* Dark theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-info {\r\n border-left: 4px solid #6dd5ed;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-success {\r\n border-left: 4px solid #38ef7d;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-warning {\r\n border-left: 4px solid #f5a623;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-error {\r\n border-left: 4px solid #f45c43;\r\n}\r\n\r\n.robot-toast-message.message-enter {\r\n animation: message-enter 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-message.message-exit {\r\n animation: message-exit 0.3s ease-in forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* CLOSE BUTTON */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-close {\r\n position: absolute;\r\n top: 4px;\r\n right: 4px;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n opacity: 0.6;\r\n transition: opacity 0.2s;\r\n padding: 0;\r\n width: 28px;\r\n height: 28px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: currentColor;\r\n}\r\n\r\n.robot-toast-close:hover {\r\n opacity: 1;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* DRAG HINT */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-drag-hint {\r\n position: absolute;\r\n left: 8px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 3px;\r\n opacity: 0.4;\r\n}\r\n\r\n.robot-toast-drag-hint span {\r\n display: block;\r\n width: 4px;\r\n height: 4px;\r\n border-radius: 50%;\r\n background: currentColor;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* BODY — the message zone. Always present, always owns its own padding. */\r\n/* Right padding leaves clear room for the absolute close button. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-body {\r\n padding: 10px 40px 10px 14px;\r\n}\r\n\r\n.robot-toast-text {\r\n font-size: 14px;\r\n line-height: 1.5;\r\n word-break: break-word;\r\n white-space: pre-wrap;\r\n font-weight: 500;\r\n min-width: 0;\r\n min-height: 1.5em;\r\n /* No padding-bottom here — body's padding-bottom handles spacing toward\r\n whichever section follows (footer, progress bar, or nothing). */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* FOOTER — the button zone. Rendered only when buttons.length > 0. */\r\n/* Owns its own bottom padding so there are no conditional margins anywhere. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-footer {\r\n /*\r\n * Symmetric vertical padding (10px top + 10px bottom) — matches body so\r\n * the two sections feel like equally-weighted \"cards\" stacked inside the\r\n * toast. This is intentional even though it doubles the gap between text\r\n * and buttons (10 body-bottom + 10 footer-top = 20px); the visual balance\r\n * matters more than the gap-tightness.\r\n */\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n}\r\n\r\n/* A row inside the footer. data-count drives width distribution — pure CSS,\r\n * no JS-side layout code. */\r\n.robot-toast-row {\r\n display: flex;\r\n gap: 6px;\r\n align-items: center;\r\n}\r\n\r\n/* 1 button in its row → content-sized, left-aligned (flex default) */\r\n.robot-toast-row[data-count=\"1\"] .robot-toast-btn {\r\n /* nothing — intrinsic width, flex-start alignment */\r\n}\r\n\r\n/* 2 or 3 buttons in a row → equal shares, filling the row's width */\r\n.robot-toast-row[data-count=\"2\"] .robot-toast-btn,\r\n.robot-toast-row[data-count=\"3\"] .robot-toast-btn {\r\n flex: 1;\r\n min-width: 0; /* let long labels shrink without breaking the 50/50 split */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* INLINE BUTTONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-btn {\r\n appearance: none;\r\n font: inherit;\r\n font-size: 12px;\r\n font-weight: 500;\r\n line-height: 1;\r\n padding: 6px 12px;\r\n border-radius: 5px;\r\n cursor: pointer;\r\n transition: background 0.15s ease, color 0.15s ease, transform 0.05s ease;\r\n white-space: nowrap;\r\n background: transparent;\r\n color: #52525b;\r\n border: 1px solid #e4e4e7;\r\n}\r\n.robot-toast-btn:hover { background: #f4f4f5; color: #18181b; }\r\n.robot-toast-btn:active { transform: scale(0.97); }\r\n\r\n/*\r\n * Solo CTA: when the toast has exactly one button, it's implicitly the\r\n * primary action. Render it filled/dark so it feels decisive (Undo / Retry\r\n * UX). A multi-button toast drops back to all-neutral — the caller picks a\r\n * primary via its own className.\r\n *\r\n * \"Exactly one button total\" = the single row has data-count=\"1\" AND is the\r\n * only row in the footer (covers the n=1 case; n=4 also has data-count rows\r\n * but they're paired, not only-child).\r\n */\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #18181b;\r\n color: #fafafa;\r\n border-color: #18181b;\r\n font-weight: 600;\r\n}\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #000;\r\n border-color: #000;\r\n color: #fafafa;\r\n}\r\n\r\n/* Dark theme — inverted neutral */\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn {\r\n color: #a1a1aa;\r\n border-color: #3f3f46;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn:hover {\r\n background: #27272a;\r\n color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #fafafa;\r\n color: #18181b;\r\n border-color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #e4e4e7;\r\n border-color: #e4e4e7;\r\n color: #18181b;\r\n}\r\n\r\n/* Colored theme — translucent whites keep contrast on any gradient */\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn {\r\n color: rgba(255, 255, 255, 0.9);\r\n border-color: rgba(255, 255, 255, 0.35);\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn:hover {\r\n background: rgba(255, 255, 255, 0.15);\r\n color: #fff;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: rgba(255, 255, 255, 0.95);\r\n color: #18181b;\r\n border-color: transparent;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #fff;\r\n color: #18181b;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* PROGRESS BAR */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-progress-container {\r\n width: 100%;\r\n height: 3px;\r\n background: rgba(0, 0, 0, 0.1);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-progress-container {\r\n background: rgba(255, 255, 255, 0.15);\r\n}\r\n\r\n.robot-toast-progress-bar {\r\n height: 100%;\r\n background: currentColor;\r\n transform-origin: left;\r\n transform: scaleX(1); /* ← starts full */\r\n}\r\n\r\n.robot-toast-theme-light.robot-toast-type-success .robot-toast-progress-bar { background: #11998e; }\r\n.robot-toast-theme-light.robot-toast-type-error .robot-toast-progress-bar { background: #eb3349; }\r\n.robot-toast-theme-light.robot-toast-type-warning .robot-toast-progress-bar { background: #fb6e3b; }\r\n.robot-toast-theme-light.robot-toast-type-info .robot-toast-progress-bar { background: #2193b0; }\r\n\r\n/* Dark theme progress bar colors */\r\n.robot-toast-theme-dark.robot-toast-type-success .robot-toast-progress-bar { background: #38ef7d; }\r\n.robot-toast-theme-dark.robot-toast-type-error .robot-toast-progress-bar { background: #f45c43; }\r\n.robot-toast-theme-dark.robot-toast-type-warning .robot-toast-progress-bar { background: #f5a623; }\r\n.robot-toast-theme-dark.robot-toast-type-info .robot-toast-progress-bar { background: #6dd5ed; }\r\n\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-auto {\r\n animation: robot-progress-countdown linear forwards;\r\n opacity: 0.8;\r\n}\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-paused {\r\n animation-play-state: paused !important;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ANIMATIONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n@keyframes robot-enter-left {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-enter-right {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-left {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n@keyframes robot-exit-right {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n\r\n@keyframes robot-idle {\r\n 0%, 100% {\r\n transform: translateY(0);\r\n }\r\n 50% {\r\n transform: translateY(-4px);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-left {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-right {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes message-enter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n@keyframes message-exit {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n}\r\n\r\n@keyframes robot-progress-countdown {\r\n from { transform: scaleX(1); }\r\n to { transform: scaleX(0); }\r\n}\r\n\r\n/* Slide transition animations */\r\n.robot-toast-robot.robot-enter-left-slide {\r\n animation: robot-enter-left-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-slide {\r\n animation: robot-enter-right-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-slide {\r\n animation: robot-exit-left-slide 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-slide {\r\n animation: robot-exit-right-slide 0.4s ease-in forwards;\r\n}\r\n\r\n/* Zoom transition animations */\r\n.robot-toast-robot.robot-enter-left-zoom,\r\n.robot-toast-robot.robot-enter-right-zoom {\r\n animation: robot-enter-zoom 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-zoom,\r\n.robot-toast-robot.robot-exit-right-zoom {\r\n animation: robot-exit-zoom 0.4s ease-in forwards;\r\n}\r\n\r\n/* Flip transition animations */\r\n.robot-toast-robot.robot-enter-left-flip {\r\n animation: robot-enter-left-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-flip {\r\n animation: robot-enter-right-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-flip {\r\n animation: robot-exit-left-flip 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-flip {\r\n animation: robot-exit-right-flip 0.4s ease-in forwards;\r\n}\r\n\r\n@keyframes robot-enter-left-slide {\r\n from { opacity: 0; transform: translateX(-60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-enter-right-slide {\r\n from { opacity: 0; transform: translateX(60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-exit-left-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(-60px); }\r\n}\r\n\r\n@keyframes robot-exit-right-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(60px); }\r\n}\r\n\r\n@keyframes robot-enter-zoom {\r\n from { opacity: 0; transform: scale(0.2); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-zoom {\r\n from { opacity: 1; transform: scale(1); }\r\n to { opacity: 0; transform: scale(0.2); }\r\n}\r\n\r\n@keyframes robot-enter-left-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-enter-right-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-exit-left-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n}\r\n\r\n@keyframes robot-exit-right-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n}\r\n\r\n/* message-enter variants */\r\n.robot-toast-message.message-enter-slide {\r\n animation: message-enter-slide 0.35s ease-out forwards;\r\n}\r\n.robot-toast-message.message-enter-zoom {\r\n animation: message-enter-zoom 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n.robot-toast-message.message-enter-flip {\r\n animation: message-enter-flip 0.4s ease-out forwards;\r\n}\r\n\r\n@keyframes message-enter-slide {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n@keyframes message-enter-zoom {\r\n from { opacity: 0; transform: scale(0.5); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n@keyframes message-enter-flip {\r\n from { opacity: 0; transform: perspective(400px) rotateX(-20deg); }\r\n to { opacity: 1; transform: perspective(400px) rotateX(0deg); }\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* RESPONSIVE - Mobile / small-screen tweaks */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n/*\r\n * Small-viewport tweaks. No !important / edge-to-edge override here — the\r\n * wrapper keeps its configured position preset and the message box stays\r\n * content-sized (just capped by max-width so it doesn't overflow). Drag\r\n * still works everywhere because no stylesheet rule competes with the\r\n * inline position the drag handler writes.\r\n */\r\n@media (max-width: 600px) {\r\n .robot-toast-wrapper {\r\n gap: 8px;\r\n max-width: calc(100vw - 24px);\r\n }\r\n\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-bottom-right { right: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-bottom-left { left: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-top-center { top: 12px; }\r\n .robot-toast-wrapper.robot-toast-bottom-right,\r\n .robot-toast-wrapper.robot-toast-bottom-left,\r\n .robot-toast-wrapper.robot-toast-bottom-center { bottom: 12px; }\r\n\r\n .robot-toast-wrapper.robot-toast-top-center,\r\n .robot-toast-wrapper.robot-toast-bottom-center {\r\n width: calc(100vw - 24px);\r\n justify-content: center;\r\n }\r\n\r\n .robot-toast-robot {\r\n width: 48px;\r\n height: 52px;\r\n }\r\n\r\n .robot-toast-message {\r\n min-width: 100px;\r\n max-width: calc(100vw - 48px - 24px - 8px);\r\n font-size: 13px;\r\n /* padding stays 0 on the outer box; sections own their spacing */\r\n }\r\n\r\n .robot-toast-body {\r\n padding: 10px 36px 10px 12px;\r\n }\r\n\r\n .robot-toast-footer {\r\n /* Same symmetric vertical padding as body — equal section weight on mobile too */\r\n padding: 10px;\r\n }\r\n\r\n .robot-toast-text {\r\n font-size: 13px;\r\n }\r\n\r\n .robot-toast-close {\r\n width: 24px;\r\n height: 24px;\r\n font-size: 20px;\r\n }\r\n}\r\n\r\n@media (max-width: 360px) {\r\n .robot-toast-robot {\r\n width: 40px;\r\n height: 44px;\r\n }\r\n .robot-toast-message {\r\n max-width: calc(100vw - 40px - 20px - 8px);\r\n }\r\n}\r\n `;\r\n\r\n const styleElement = document.createElement('style');\r\n styleElement.id = styleId;\r\n styleElement.textContent = styles;\r\n document.head.appendChild(styleElement);\r\n }\r\n}\r\n\r\nexport default InjectStyles;\r\n","/**\r\n * RobotToast v2\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * • Multi-toast support with configurable limit + queue\r\n * • Each toast is a self-contained ToastItem instance – no shared mutable state\r\n * • Sequenced robot enter → message pop-in, message pop-out → robot exit\r\n * • Full XY drag with viewport clamping; on drop the robot snaps to the\r\n * nearest screen edge (left / right) with a personality animation\r\n * • Progress bar auto-animates for the countdown; pauses correctly on hover\r\n * and drag; resumes with exact remaining time\r\n * • All event listeners are tracked and fully removed on close\r\n * • SVG-only enforcement for custom robot images; always renders at fixed size\r\n * • SSR-safe (all DOM access is guarded by typeof window / document checks)\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n */\r\n\r\nimport type { RobotToastOptions, ToastQueueItem, ToastButton } from './types';\r\nimport InjectStyles from './styles-injector';\r\n\r\n// ─── Unique ID counter ────────────────────────────────────────────────────────\r\nlet _nextId = 1;\r\nfunction nextId(): number { return _nextId++; }\r\n\r\n// ─── Vertical offset step between stacked toasts (px) ────────────────────────\r\nconst STACK_GAP = 16;\r\n\r\n/**\r\n * Split N buttons into rows according to the layout spec:\r\n * 1→[1] 2→[2] 3→[3] 4→[2,2]\r\n * 5→[3,2] 6→[3,3] 7→[3,2,2] 8→[3,3,2] 9→[3,3,3]\r\n * 10→[3,3,2,2] 11→[3,3,3,2] 12→[3,3,3,3] …\r\n * Rule: fill rows of 3 from the top. If the tail would leave a single\r\n * lonely button, steal one from the previous row so the last two rows\r\n * balance as [2, 2].\r\n */\r\nfunction chunkButtons<T>(buttons: T[]): T[][] {\r\n const n = buttons.length;\r\n if (n === 0) return [];\r\n if (n <= 3) return [buttons.slice()];\r\n if (n === 4) return [buttons.slice(0, 2), buttons.slice(2)];\r\n\r\n const rows: T[][] = [];\r\n let i = 0;\r\n while (n - i > 4) {\r\n rows.push(buttons.slice(i, i + 3));\r\n i += 3;\r\n }\r\n const rem = n - i;\r\n if (rem === 4) {\r\n rows.push(buttons.slice(i, i + 2));\r\n rows.push(buttons.slice(i + 2));\r\n } else {\r\n rows.push(buttons.slice(i));\r\n }\r\n return rows;\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n ToastItem – one live toast on screen\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass ToastItem {\r\n readonly id: number;\r\n private options: {\r\n message: string;\r\n autoClose: boolean | number;\r\n position: NonNullable<RobotToastOptions['position']>;\r\n type: NonNullable<RobotToastOptions['type']>;\r\n theme: NonNullable<RobotToastOptions['theme']>;\r\n style?: Record<string, string | number>;\r\n typeSpeed: number;\r\n robotVariant: string;\r\n hideProgressBar: boolean;\r\n pauseOnFocusLoss: boolean;\r\n draggable: boolean;\r\n nearScreen: boolean;\r\n pauseOnHover: boolean;\r\n rtl: boolean;\r\n transition: NonNullable<RobotToastOptions['transition']>;\r\n buttons?: ToastButton[];\r\n onOpen?: () => void;\r\n onClose?: () => void;\r\n };\r\n\r\n // DOM refs\r\n private wrapper: HTMLDivElement;\r\n private robotEl: HTMLDivElement;\r\n private messageBox: HTMLDivElement;\r\n private progressBar: HTMLDivElement | null = null;\r\n private messageText: HTMLDivElement;\r\n\r\n // Timer state\r\n private autoCloseDuration: number; // ms; 0 = no auto-close\r\n private remainingTime: number; // ms left on the countdown\r\n private timerStart: number | null = null; // when the current timer was set\r\n private closeTimeout: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // Interaction state\r\n private isDragging = false;\r\n private dragOffsetX = 0;\r\n private dragOffsetY = 0;\r\n private dragWidth = 0;\r\n private dragHeight = 0;\r\n private currentRobotSide: 'left' | 'right';\r\n private isHovered = false;\r\n private isFocusLost = false;\r\n private isClosed = false;\r\n\r\n // Cleanup\r\n private cleanupFns: Array<() => void> = [];\r\n\r\n // Callback to notify the manager when this toast dies\r\n private onRemove: (id: number) => void;\r\n\r\n constructor(id: number, options: RobotToastOptions, onRemove: (id: number) => void) {\r\n this.id = id;\r\n this.onRemove = onRemove;\r\n\r\n // ── Resolve all options with defaults ──────────────────────────────────\r\n const resolved = {\r\n message: options.message,\r\n autoClose: options.autoClose ?? 5000,\r\n position: options.position ?? 'bottom-right',\r\n type: options.type ?? 'default',\r\n theme: options.theme ?? 'light',\r\n style: options.style,\r\n typeSpeed: options.typeSpeed ?? 30,\r\n robotVariant: options.robotVariant ?? '',\r\n hideProgressBar: options.hideProgressBar ?? false,\r\n pauseOnFocusLoss: options.pauseOnFocusLoss ?? true,\r\n draggable: options.draggable ?? true,\r\n nearScreen: options.nearScreen ?? true,\r\n pauseOnHover: options.pauseOnHover ?? true,\r\n rtl: options.rtl ?? false,\r\n transition: options.transition ?? 'bounce',\r\n buttons: options.buttons,\r\n onOpen: options.onOpen,\r\n onClose: options.onClose,\r\n };\r\n\r\n this.options = resolved;\r\n \r\n // Determine initial robot side based on nearScreen\r\n // nearScreen: true → robot near screen edge (position's side)\r\n // nearScreen: false → robot away from screen edge (opposite side)\r\n const positionIsLeft = resolved.position.includes('left');\r\n \r\n let initialSide: 'left' | 'right';\r\n if (resolved.nearScreen) {\r\n // Robot near edge: follow position\r\n initialSide = positionIsLeft ? 'left' : 'right';\r\n } else {\r\n // Robot away from edge: opposite of position\r\n initialSide = positionIsLeft ? 'right' : 'left';\r\n }\r\n this.currentRobotSide = initialSide;\r\n this.autoCloseDuration = typeof resolved.autoClose === 'number'\r\n ? resolved.autoClose\r\n : (resolved.autoClose ? 5000 : 0);\r\n this.remainingTime = this.autoCloseDuration;\r\n\r\n // ── Build DOM ──────────────────────────────────────────────────────────\r\n this.wrapper = this.buildWrapper();\r\n this.robotEl = this.buildRobot();\r\n this.messageBox = this.buildMessageBox();\r\n this.messageText = this.messageBox.querySelector('.robot-toast-text')!;\r\n this.progressBar = this.messageBox.querySelector('.robot-toast-progress-bar');\r\n\r\n // Empty message → hide message box entirely (only the robot shows)\r\n if (resolved.message === '') {\r\n this.messageBox.classList.add('robot-toast-empty');\r\n }\r\n\r\n this.assembleLayout();\r\n document.body.appendChild(this.wrapper);\r\n\r\n // ── Wire interactions ──────────────────────────────────────────────────\r\n if (resolved.draggable) this.initDrag();\r\n if (resolved.pauseOnFocusLoss) this.initFocusWatcher();\r\n if (resolved.pauseOnHover) this.initHoverWatcher();\r\n\r\n // ── Kick off the entrance sequence ─────────────────────────────────────\r\n requestAnimationFrame(() => this.playEntrance());\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n close(): void {\r\n if (this.isClosed) return;\r\n this.isClosed = true;\r\n\r\n this.cancelTimer();\r\n this.cleanupFns.forEach(fn => fn());\r\n this.cleanupFns = [];\r\n\r\n this.playExit(() => {\r\n if (this.wrapper.parentNode) {\r\n this.wrapper.parentNode.removeChild(this.wrapper);\r\n }\r\n this.options.onClose?.();\r\n this.onRemove(this.id);\r\n });\r\n }\r\n\r\n /** Shift this toast vertically by `delta` px (used by manager for stacking) */\r\n shiftVertical(bottomPx: number): void {\r\n const pos = this.options.position;\r\n if (pos.startsWith('bottom')) {\r\n this.wrapper.style.bottom = `${bottomPx}px`;\r\n } else {\r\n this.wrapper.style.top = `${bottomPx}px`;\r\n }\r\n }\r\n\r\n getWrapperHeight(): number {\r\n return this.wrapper.getBoundingClientRect().height || 90;\r\n }\r\n\r\n // ── DOM builders ───────────────────────────────────────────────────────────\r\n\r\n private buildWrapper(): HTMLDivElement {\r\n const w = document.createElement('div');\r\n const classes = ['robot-toast-wrapper', `robot-toast-${this.options.position}`];\r\n if (this.options.rtl) classes.push('robot-toast-rtl');\r\n w.className = classes.join(' ');\r\n\r\n // ARIA: error/warning are assertive (role=alert), everything else polite (role=status).\r\n const assertive = this.options.type === 'error' || this.options.type === 'warning';\r\n w.setAttribute('role', assertive ? 'alert' : 'status');\r\n w.setAttribute('aria-live', assertive ? 'assertive' : 'polite');\r\n w.setAttribute('aria-atomic', 'true');\r\n\r\n return w;\r\n }\r\n\r\n /**\r\n * Decides what a given `robotVariant` resolves to:\r\n * - `'hidden'` — not shown at all (omitted, '' empty, 'none' alias, or unusable string)\r\n * - `'default'` — built-in inline SVG\r\n * - `'image'` — external image source (data URL or file path)\r\n */\r\n private resolveVariant(): 'hidden' | 'default' | 'image' {\r\n const v = this.options.robotVariant;\r\n if (!v || v === 'none') return 'hidden';\r\n if (v === 'default') return 'default';\r\n const ALLOWED_EXTS = ['.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp'];\r\n const isDataUrl = v.startsWith('data:');\r\n const isAllowed = isDataUrl\r\n || ALLOWED_EXTS.some(ext => v.toLowerCase().endsWith(ext));\r\n return isAllowed ? 'image' : 'hidden';\r\n }\r\n\r\n private buildRobot(): HTMLDivElement {\r\n const r = document.createElement('div');\r\n r.className = 'robot-toast-robot';\r\n\r\n const kind = this.resolveVariant();\r\n\r\n if (kind === 'hidden') {\r\n r.style.display = 'none';\r\n return r;\r\n }\r\n\r\n if (kind === 'default') {\r\n r.innerHTML = this.getBuiltinSVG();\r\n return r;\r\n }\r\n\r\n // kind === 'image' — data URL or recognized path. Fall back to the\r\n // built-in SVG only if the image fails to load at runtime (the user\r\n // clearly intended a robot, so we don't want an empty slot).\r\n const img = document.createElement('img');\r\n img.src = this.options.robotVariant;\r\n img.alt = 'Robot';\r\n img.setAttribute('width', '65');\r\n img.setAttribute('height', '70');\r\n img.style.cssText = 'width:100%;height:100%;object-fit:contain;display:block;';\r\n img.onerror = () => { r.innerHTML = this.getBuiltinSVG(); };\r\n r.appendChild(img);\r\n return r;\r\n }\r\n\r\n private buildMessageBox(): HTMLDivElement {\r\n const box = document.createElement('div');\r\n const classes = [\r\n 'robot-toast-message',\r\n `robot-toast-type-${this.options.type}`,\r\n `robot-toast-theme-${this.options.theme}`,\r\n ].filter(Boolean);\r\n box.className = classes.join(' ');\r\n box.style.cursor = this.options.draggable ? 'grab' : 'default';\r\n\r\n // Apply inline styles if provided (takes precedence over theme colors)\r\n if (this.options.style) {\r\n Object.entries(this.options.style).forEach(([key, value]) => {\r\n const camelCaseKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (box.style as any)[camelCaseKey] = value;\r\n });\r\n }\r\n\r\n // ── Layout ────────────────────────────────────────────────────────────\r\n // Discrete sections, each owning its own spacing. The outer `box` has no\r\n // padding — bodyPad and footerPad live on the sections themselves, so\r\n // optional pieces (footer, progress bar) can appear/disappear without\r\n // us having to juggle conditional margins anywhere else.\r\n\r\n // Close button — absolute, top-right of the whole box (outside sections)\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'robot-toast-close';\r\n closeBtn.innerHTML = '×';\r\n closeBtn.title = 'Dismiss';\r\n closeBtn.type = 'button';\r\n closeBtn.setAttribute('aria-label', 'Dismiss notification');\r\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.close(); });\r\n box.appendChild(closeBtn);\r\n\r\n // Section 1 — body (message text). Always present.\r\n const body = document.createElement('div');\r\n body.className = 'robot-toast-body';\r\n const text = document.createElement('div');\r\n text.className = 'robot-toast-text';\r\n body.appendChild(text);\r\n box.appendChild(body);\r\n\r\n // Section 2 — footer (button rows). Rendered only when buttons exist.\r\n if (this.options.buttons && this.options.buttons.length > 0) {\r\n const footer = document.createElement('div');\r\n footer.className = 'robot-toast-footer';\r\n // Chunk into rows per the layout spec (1→[1] 4→[2,2] 5→[3,2] 7→[3,2,2] …)\r\n // then emit each row with `data-count` so CSS can pick the right split.\r\n const rows = chunkButtons(this.options.buttons);\r\n rows.forEach(rowBtns => {\r\n const row = document.createElement('div');\r\n row.className = 'robot-toast-row';\r\n row.setAttribute('data-count', String(rowBtns.length));\r\n rowBtns.forEach(btn => row.appendChild(this.buildButton(btn)));\r\n footer.appendChild(row);\r\n });\r\n box.appendChild(footer);\r\n }\r\n\r\n // Progress bar — unchanged, always last.\r\n const pContainer = document.createElement('div');\r\n pContainer.className = 'robot-toast-progress-container';\r\n if (this.options.hideProgressBar) pContainer.style.display = 'none';\r\n\r\n const pBar = document.createElement('div');\r\n pBar.className = 'robot-toast-progress-bar';\r\n\r\n pContainer.appendChild(pBar);\r\n box.appendChild(pContainer);\r\n\r\n return box;\r\n }\r\n\r\n private buildButton(button: ToastButton): HTMLButtonElement {\r\n const el = document.createElement('button');\r\n el.type = 'button';\r\n el.className = button.className\r\n ? `robot-toast-btn ${button.className}`\r\n : 'robot-toast-btn';\r\n el.textContent = button.label;\r\n\r\n // Inline style: same kebab → camel conversion the message-level `style`\r\n // option uses, so consumers can pass either form. Applied after className\r\n // so it takes precedence over class-based rules.\r\n if (button.style) {\r\n Object.entries(button.style).forEach(([key, value]) => {\r\n const camelKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (el.style as unknown as Record<string, string | number>)[camelKey] = value;\r\n });\r\n }\r\n\r\n el.addEventListener('click', (e) => {\r\n // Stop the click from bubbling to drag / hover handlers on the wrapper.\r\n e.stopPropagation();\r\n // Fire the callback, then dismiss. If the callback throws we still\r\n // close — otherwise a bad handler strands the toast on screen.\r\n try {\r\n button.onClick(e);\r\n } catch (err) {\r\n console.error('[robot-toast] button onClick threw:', err);\r\n }\r\n this.close();\r\n });\r\n return el;\r\n }\r\n\r\n private assembleLayout(): void {\r\n const { rtl } = this.options;\r\n this.wrapper.innerHTML = '';\r\n\r\n // Decide order: rtl flips everything, robot side controls natural order\r\n const robotOnLeft = rtl ? this.currentRobotSide === 'right' : this.currentRobotSide === 'left';\r\n\r\n if (robotOnLeft) {\r\n this.wrapper.appendChild(this.robotEl);\r\n this.wrapper.appendChild(this.messageBox);\r\n } else {\r\n this.wrapper.appendChild(this.messageBox);\r\n this.wrapper.appendChild(this.robotEl);\r\n }\r\n }\r\n\r\n // ── Sequenced animations ───────────────────────────────────────────────────\r\n\r\n private playEntrance(): void {\r\n // Step 1 – wrapper becomes visible\r\n this.wrapper.classList.add('robot-toast-visible');\r\n\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const showMessage = () => {\r\n if (messageHidden) {\r\n // No text box – skip pop-in, still fire onOpen and start timer\r\n this.options.onOpen?.();\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n // Message pops in\r\n const msgEnterClass = this.options.transition === 'bounce'\r\n ? 'message-enter'\r\n : `message-enter-${this.options.transition}`;\r\n this.messageBox.classList.add(msgEnterClass);\r\n\r\n const onMsgEntered = () => {\r\n this.messageBox.removeEventListener('animationend', onMsgEntered);\r\n this.messageBox.classList.remove(msgEnterClass);\r\n this.messageBox.style.opacity = '1';\r\n this.messageBox.style.transform = 'none';\r\n\r\n this.options.onOpen?.();\r\n this.startTyping();\r\n };\r\n this.messageBox.addEventListener('animationend', onMsgEntered, { once: true });\r\n };\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot entrance, go straight to message\r\n showMessage();\r\n } else {\r\n // Step 2 – robot runs in with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const enterClass = `robot-enter-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(enterClass);\r\n\r\n const onRobotEntered = () => {\r\n this.robotEl.removeEventListener('animationend', onRobotEntered);\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(enterClass);\r\n this.robotEl.classList.add('robot-idle');\r\n showMessage();\r\n };\r\n this.robotEl.addEventListener('animationend', onRobotEntered, { once: true });\r\n }\r\n }\r\n\r\n private playExit(done: () => void): void {\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const afterMsg = () => {\r\n this.messageBox.removeEventListener('animationend', afterMsg);\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot exit, just fade wrapper\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n } else {\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n\r\n // Step 2 – robot runs out with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const exitClass = `robot-exit-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(exitClass);\r\n\r\n const afterRobot = () => {\r\n this.robotEl.removeEventListener('animationend', afterRobot);\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n };\r\n this.robotEl.addEventListener('animationend', afterRobot, { once: true });\r\n }\r\n };\r\n\r\n if (messageHidden) {\r\n // No text box – skip the collapse step entirely\r\n afterMsg();\r\n } else {\r\n this.messageBox.classList.add('message-exit');\r\n this.messageBox.addEventListener('animationend', afterMsg, { once: true });\r\n }\r\n }\r\n\r\n // ── Typing effect ──────────────────────────────────────────────────────────\r\n\r\n private startTyping(): void {\r\n const { message, typeSpeed } = this.options;\r\n const el = this.messageText;\r\n\r\n if (typeSpeed === 0) {\r\n // Instant – no animation\r\n el.textContent = message;\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n\r\n let index = 0;\r\n let active = true;\r\n\r\n // Register cleanup so that if toast is closed mid-type the loop stops\r\n this.cleanupFns.push(() => { active = false; });\r\n\r\n const tick = () => {\r\n if (!active) return;\r\n if (index < message.length) {\r\n el.textContent += message.charAt(index++);\r\n setTimeout(tick, typeSpeed);\r\n } else {\r\n this.afterTypingComplete();\r\n }\r\n };\r\n tick();\r\n }\r\n\r\n private afterTypingComplete(): void {\r\n // Always start auto-progress-bar animation (unless hidden)\r\n if (this.autoCloseDuration > 0 && !this.options.hideProgressBar && this.progressBar) {\r\n this.progressBar.style.animationDuration = `${this.autoCloseDuration}ms`; // set duration FIRST\r\n void this.progressBar.offsetWidth; // flush\r\n this.progressBar.classList.add('robot-toast-progress-auto'); // THEN start\r\n if (this.isHovered || this.isFocusLost) {\r\n this.progressBar.classList.add('robot-toast-progress-paused');\r\n }\r\n }\r\n\r\n // Start the close timer unless something is currently pausing it\r\n if (!this.isHovered && !this.isFocusLost) {\r\n this.startTimer();\r\n }\r\n }\r\n\r\n // ── Timer management ───────────────────────────────────────────────────────\r\n\r\n private startTimer(): void {\r\n if (this.autoCloseDuration <= 0 || this.remainingTime <= 0) return;\r\n this.timerStart = Date.now();\r\n this.closeTimeout = setTimeout(() => this.close(), this.remainingTime);\r\n }\r\n\r\n private pauseTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n if (this.timerStart !== null) {\r\n const elapsed = Date.now() - this.timerStart;\r\n this.remainingTime = Math.max(0, this.remainingTime - elapsed);\r\n this.timerStart = null;\r\n }\r\n }\r\n this.progressBar?.classList.add('robot-toast-progress-paused');\r\n }\r\n\r\n private resumeTimer(): void {\r\n if (this.isHovered || this.isFocusLost || this.isDragging) return;\r\n this.progressBar?.classList.remove('robot-toast-progress-paused');\r\n this.startTimer();\r\n }\r\n\r\n private cancelTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n }\r\n }\r\n\r\n // ── Hover watcher ──────────────────────────────────────────────────────────\r\n\r\n private initHoverWatcher(): void {\r\n const onEnter = () => {\r\n this.isHovered = true;\r\n this.pauseTimer();\r\n };\r\n const onLeave = () => {\r\n this.isHovered = false;\r\n this.resumeTimer();\r\n };\r\n this.wrapper.addEventListener('mouseenter', onEnter);\r\n this.wrapper.addEventListener('mouseleave', onLeave);\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('mouseenter', onEnter);\r\n this.wrapper.removeEventListener('mouseleave', onLeave);\r\n });\r\n }\r\n\r\n // ── Focus watcher ──────────────────────────────────────────────────────────\r\n\r\n private initFocusWatcher(): void {\r\n const onBlur = () => {\r\n this.isFocusLost = true;\r\n this.pauseTimer();\r\n };\r\n const onFocus = () => {\r\n this.isFocusLost = false;\r\n this.resumeTimer();\r\n };\r\n window.addEventListener('blur', onBlur);\r\n window.addEventListener('focus', onFocus);\r\n this.cleanupFns.push(() => {\r\n window.removeEventListener('blur', onBlur);\r\n window.removeEventListener('focus', onFocus);\r\n });\r\n }\r\n\r\n // ── Drag ──────────────────────────────────────────────────────────────────\r\n\r\n private initDrag(): void {\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Pointer events (covers both mouse & touch via pointer API) ──────────\r\n const onPointerDown = (e: PointerEvent) => {\r\n // Clicks / taps on the close button or any inline action button must\r\n // never initiate a drag — otherwise the user can't actually press them.\r\n if ((e.target as HTMLElement).closest(\r\n '.robot-toast-close, .robot-toast-btn'\r\n )) return;\r\n // Only primary button / first touch\r\n if (e.button !== undefined && e.button !== 0) return;\r\n\r\n e.preventDefault();\r\n this.isDragging = true;\r\n this.pauseTimer();\r\n\r\n // \"Detach\" the wrapper from its CSS-positioned slot by converting its\r\n // current visual position into explicit inline top/left values.\r\n const rect = this.wrapper.getBoundingClientRect();\r\n this.wrapper.classList.add('robot-toast-dragging');\r\n\r\n // Inline position so the wrapper sits exactly where it was\r\n this.wrapper.style.top = `${rect.top}px`;\r\n this.wrapper.style.left = `${rect.left}px`;\r\n this.wrapper.style.right = 'auto';\r\n this.wrapper.style.bottom = 'auto';\r\n this.wrapper.style.transform = 'none';\r\n\r\n // Cache size — width/height don't change during drag, so we avoid a\r\n // layout read on every pointermove (major mobile jank source).\r\n this.dragWidth = rect.width;\r\n this.dragHeight = rect.height;\r\n\r\n // Offset = where inside the wrapper the pointer grabbed\r\n this.dragOffsetX = e.clientX - rect.left;\r\n this.dragOffsetY = e.clientY - rect.top;\r\n\r\n this.messageBox.style.cursor = 'grabbing';\r\n this.wrapper.setPointerCapture(e.pointerId);\r\n };\r\n\r\n const onPointerMove = (e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n e.preventDefault();\r\n\r\n // Use cached width/height + live window dims — no layout flush.\r\n const maxX = window.innerWidth - this.dragWidth;\r\n const maxY = window.innerHeight - this.dragHeight;\r\n\r\n const newLeft = Math.max(0, Math.min(e.clientX - this.dragOffsetX, maxX));\r\n const newTop = Math.max(0, Math.min(e.clientY - this.dragOffsetY, maxY));\r\n\r\n this.wrapper.style.left = `${newLeft}px`;\r\n this.wrapper.style.top = `${newTop}px`;\r\n };\r\n\r\n const onPointerUp = (_e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n this.isDragging = false;\r\n this.wrapper.classList.remove('robot-toast-dragging');\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Snap to nearest horizontal screen edge ────────────────────────────\r\n // One getBoundingClientRect() on drop is fine — it's a single layout\r\n // flush per release, not per frame. This is more robust than reading\r\n // inline style.left, which can lag the rendered position in edge cases\r\n // (parent transforms, pending animations, etc.).\r\n const rect = this.wrapper.getBoundingClientRect();\r\n const currentTop = rect.top;\r\n const midX = rect.left + rect.width / 2;\r\n const centerX = window.innerWidth / 2;\r\n\r\n // Determine which edge to snap to based on which half the center is in\r\n const snapToLeft = midX < centerX;\r\n\r\n // Determine robot side based on nearScreen setting\r\n const newRobotSide: 'left' | 'right' = this.options.nearScreen\r\n ? (snapToLeft ? 'left' : 'right')\r\n : (snapToLeft ? 'right' : 'left');\r\n\r\n // Determine final resting left position (20px margin from edge)\r\n const finalLeft = snapToLeft ? 20 : window.innerWidth - this.dragWidth - 20;\r\n const finalTop = Math.max(20, Math.min(currentTop, window.innerHeight - this.dragHeight - 20));\r\n\r\n // Re-enable transitions for the snap glide\r\n this.wrapper.style.transition =\r\n 'left 0.45s cubic-bezier(0.34,1.56,0.64,1), top 0.4s cubic-bezier(0.34,1.56,0.64,1)';\r\n this.wrapper.style.left = `${finalLeft}px`;\r\n this.wrapper.style.top = `${finalTop}px`;\r\n\r\n // Update robot side if it changed\r\n if (newRobotSide !== this.currentRobotSide) {\r\n this.currentRobotSide = newRobotSide;\r\n\r\n // Use CSS order to visually reorder (no DOM detach = no animation restart)\r\n const robotOnLeft = newRobotSide === 'left';\r\n this.robotEl.style.order = robotOnLeft ? '0' : '1';\r\n this.messageBox.style.order = robotOnLeft ? '1' : '0';\r\n\r\n // Snap animation\r\n const snapClass = newRobotSide === 'left' ? 'robot-snap-left' : 'robot-snap-right';\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n this.robotEl.classList.add(snapClass);\r\n this.robotEl.addEventListener('animationend', () => {\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(snapClass);\r\n this.robotEl.classList.add('robot-idle');\r\n }, { once: true });\r\n }\r\n const clearTransition = () => {\r\n this.wrapper.style.transition = '';\r\n };\r\n setTimeout(clearTransition, 500);\r\n\r\n // Resume the auto-close timer\r\n this.resumeTimer();\r\n };\r\n\r\n this.wrapper.addEventListener('pointerdown', onPointerDown);\r\n this.wrapper.addEventListener('pointermove', onPointerMove);\r\n this.wrapper.addEventListener('pointerup', onPointerUp);\r\n this.wrapper.addEventListener('pointercancel', onPointerUp);\r\n\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('pointerdown', onPointerDown);\r\n this.wrapper.removeEventListener('pointermove', onPointerMove);\r\n this.wrapper.removeEventListener('pointerup', onPointerUp);\r\n this.wrapper.removeEventListener('pointercancel', onPointerUp);\r\n });\r\n }\r\n\r\n // ── Built-in robot SVG ─────────────────────────────────────────────────────\r\n\r\n private getBuiltinSVG(): string {\r\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 120\"\r\n width=\"100%\" height=\"100%\" role=\"img\" aria-label=\"Robot\">\r\n <defs>\r\n <linearGradient id=\"rtGrad${this.id}\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#E2F0FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#B8D8FF\"/>\r\n </linearGradient>\r\n <linearGradient id=\"rtAccent${this.id}\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#7CB9FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#4A90D9\"/>\r\n </linearGradient>\r\n </defs>\r\n <!-- Antenna -->\r\n <line x1=\"50\" y1=\"4\" x2=\"50\" y2=\"18\" stroke=\"#2B3A55\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\r\n <circle cx=\"50\" cy=\"4\" r=\"4\" fill=\"#FF6B6B\"/>\r\n <!-- Head -->\r\n <rect x=\"24\" y=\"18\" width=\"52\" height=\"40\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Eyes -->\r\n <circle cx=\"38\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"62\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"40\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <circle cx=\"64\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <!-- Mouth -->\r\n <path d=\"M 38 50 Q 50 58 62 50\" stroke=\"#2B3A55\" stroke-width=\"2\"\r\n fill=\"none\" stroke-linecap=\"round\"/>\r\n <!-- Neck -->\r\n <rect x=\"44\" y=\"58\" width=\"12\" height=\"8\" rx=\"3\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <!-- Body -->\r\n <rect x=\"22\" y=\"66\" width=\"56\" height=\"44\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Chest panel -->\r\n <rect x=\"34\" y=\"76\" width=\"32\" height=\"20\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <circle cx=\"42\" cy=\"86\" r=\"3\" fill=\"#FF6B6B\"/>\r\n <circle cx=\"50\" cy=\"86\" r=\"3\" fill=\"#FFD700\"/>\r\n <circle cx=\"58\" cy=\"86\" r=\"3\" fill=\"#6BFF8A\"/>\r\n <!-- Arms -->\r\n <rect x=\"4\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <rect x=\"78\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Legs -->\r\n <rect x=\"30\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <rect x=\"54\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n </svg>`;\r\n }\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n RobotToastManager – global singleton that owns all ToastItems\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass RobotToastManager {\r\n private static _instance: RobotToastManager | null = null;\r\n\r\n private activeToasts: ToastItem[] = [];\r\n private queue: ToastQueueItem[] = [];\r\n private globalLimit = 0; // 0 = unlimited; overridden per-show call\r\n\r\n private constructor() {\r\n new InjectStyles();\r\n }\r\n\r\n static getInstance(): RobotToastManager {\r\n if (!RobotToastManager._instance) {\r\n RobotToastManager._instance = new RobotToastManager();\r\n }\r\n return RobotToastManager._instance;\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n show(options: RobotToastOptions): number {\r\n if (typeof document === 'undefined') return -1;\r\n\r\n const id = nextId();\r\n const limit = options.limit ?? this.globalLimit;\r\n\r\n if (limit > 0 && this.activeToasts.length >= limit) {\r\n // Queue it for later\r\n this.queue.push({ options, id });\r\n return id;\r\n }\r\n\r\n this.spawnToast(options, id);\r\n return id;\r\n }\r\n\r\n closeAll(): void {\r\n this.queue = [];\r\n [...this.activeToasts].forEach(t => t.close());\r\n }\r\n\r\n closeById(id: number): void {\r\n const toast = this.activeToasts.find(t => t.id === id);\r\n if (toast) toast.close();\r\n\r\n // Also remove from queue if it hasn't spawned yet\r\n this.queue = this.queue.filter(q => q.id !== id);\r\n }\r\n\r\n // ── Internal ───────────────────────────────────────────────────────────────\r\n\r\n private spawnToast(options: RobotToastOptions, id: number): void {\r\n const toast = new ToastItem(id, options, (doneId) => this.handleRemoved(doneId));\r\n const newestOnTop = options.newestOnTop ?? false;\r\n\r\n if (newestOnTop) {\r\n this.activeToasts.unshift(toast);\r\n } else {\r\n this.activeToasts.push(toast);\r\n }\r\n\r\n this.restack();\r\n }\r\n\r\n private handleRemoved(id: number): void {\r\n this.activeToasts = this.activeToasts.filter(t => t.id !== id);\r\n this.restack();\r\n\r\n // Dequeue next if any\r\n if (this.queue.length > 0) {\r\n const next = this.queue.shift()!;\r\n // Small delay so the stack reflows are visible\r\n setTimeout(() => this.spawnToast(next.options, next.id), 120);\r\n }\r\n }\r\n\r\n /**\r\n * Recalculate the vertical position of every active toast so they stack\r\n * neatly without overlap. Works for both top-* and bottom-* positions.\r\n */\r\n private restack(): void {\r\n // Group by position string\r\n const groups: Record<string, ToastItem[]> = {};\r\n this.activeToasts.forEach(t => {\r\n const pos = (t as any).options.position as string;\r\n if (!groups[pos]) groups[pos] = [];\r\n groups[pos].push(t);\r\n });\r\n\r\n Object.keys(groups).forEach(pos => {\r\n const list = groups[pos];\r\n let offset = 20; // initial edge margin px\r\n\r\n list.forEach((toast) => {\r\n toast.shiftVertical(offset);\r\n offset += toast.getWrapperHeight() + STACK_GAP;\r\n });\r\n });\r\n }\r\n}\r\n\r\nexport { RobotToastManager as default, RobotToastManager };","/**\r\n * RobotToast Utilities v2\r\n * Helper functions for safer access to the RobotToast API.\r\n * Handles async readiness checks, SSR guards, and error boundaries.\r\n * Useful when loading robot-toast via a CDN <script> tag.\r\n */\r\n\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\n\r\n/**\r\n * Wait for window.RobotToast to be available, up to `timeout` ms.\r\n * Resolves immediately if it is already loaded.\r\n * Useful when the library is loaded via a <script> tag and you need\r\n * to call it from another script that may execute first.\r\n */\r\nexport function ensureRobotToastReady(timeout = 5000): Promise<RobotToastAPI> {\r\n return new Promise((resolve, reject) => {\r\n if (typeof window === 'undefined') {\r\n reject(new Error('[RobotToast] Cannot run outside of a browser environment.'));\r\n return;\r\n }\r\n\r\n if (window.RobotToast) {\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n const interval = setInterval(() => {\r\n if (window.RobotToast) {\r\n clearInterval(interval);\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n if (Date.now() - startTime >= timeout) {\r\n clearInterval(interval);\r\n reject(new Error(`[RobotToast] Failed to load within ${timeout}ms.`));\r\n }\r\n }, 80);\r\n });\r\n}\r\n\r\n/**\r\n * Show a robot toast notification.\r\n * Waits for the library to be ready before showing.\r\n * Returns the toast id or -1 on failure.\r\n */\r\nexport async function showRobotToast(options: RobotToastOptions): Promise<number> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n return api.show(options);\r\n } catch (err) {\r\n console.error('[RobotToast] showRobotToast failed:', err);\r\n return -1;\r\n }\r\n}\r\n\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\nexport async function closeAllRobotToasts(): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeAll();\r\n } catch (err) {\r\n console.error('[RobotToast] closeAllRobotToasts failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Close a specific toast by the id returned from show().\r\n */\r\nexport async function closeRobotToastById(id: number): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeById(id);\r\n } catch (err) {\r\n console.error('[RobotToast] closeRobotToastById failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Get the RobotToast API instance.\r\n */\r\nexport async function getRobotToastInstance(): Promise<RobotToastAPI> {\r\n return ensureRobotToastReady();\r\n}","/**\r\n * RobotToast Types & Constants\r\n * Type definitions and constant arrays for the robot toast notification library\r\n */\r\n\r\n/** Array of all valid toast positions */\r\nexport const TOAST_POSITIONS = [\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] as const;\r\n\r\n/** Array of all valid toast types */\r\nexport const TOAST_TYPES = ['default', 'info', 'success', 'warning', 'error'] as const;\r\n\r\n/** Array of all valid toast themes */\r\nexport const TOAST_THEMES = ['light', 'dark', 'colored'] as const;\r\n\r\n/** Array of all valid transition animations */\r\nexport const TOAST_TRANSITIONS = ['bounce', 'slide', 'zoom', 'flip'] as const;\r\n\r\n/** Type derived from TOAST_POSITIONS constant */\r\nexport type ToastPosition = typeof TOAST_POSITIONS[number];\r\n\r\n/** Type derived from TOAST_TYPES constant */\r\nexport type ToastType = typeof TOAST_TYPES[number];\r\n\r\n/** Type derived from TOAST_THEMES constant */\r\nexport type ToastTheme = typeof TOAST_THEMES[number];\r\n\r\n/** Type derived from TOAST_TRANSITIONS constant */\r\nexport type TransitionType = typeof TOAST_TRANSITIONS[number];\r\n\r\n/**\r\n * A button rendered inside the toast. Pass an array of these as `buttons`\r\n * to add inline CTAs like \"Undo\" / \"Retry\" / \"Cancel\":\r\n *\r\n * toast({\r\n * message: 'File deleted',\r\n * buttons: [\r\n * { label: 'Undo', onClick: () => restore() },\r\n * ],\r\n * });\r\n *\r\n * Buttons render in array order. Clicking any of them fires its `onClick`\r\n * and then closes the toast. Visual hierarchy is up to you — pass a custom\r\n * `className` to override the default neutral style (e.g. to mark the\r\n * primary CTA as filled/bold and a secondary as muted).\r\n */\r\nexport interface ToastButton {\r\n /** Visible button text. Keep it short (1–2 words). */\r\n label: string;\r\n /** Fired before the toast closes. Receives the click event. */\r\n onClick: (event: MouseEvent) => void;\r\n /**\r\n * Optional CSS class(es) appended to the button element. Use this when you\r\n * have a stylesheet rule like `.my-primary { background: black; color: white }`\r\n * defined elsewhere in your app and want to apply it to this button.\r\n */\r\n className?: string;\r\n /**\r\n * Optional inline styles applied directly to the button element. Use this\r\n * when you don't want to add a CSS rule to your stylesheet — pass an object\r\n * of camelCased properties (or kebab-case keys; both work):\r\n *\r\n * style: { background: 'black', color: 'white', borderRadius: '8px' }\r\n *\r\n * Takes precedence over className-based rules and over the default neutral\r\n * (and solo-CTA) button styles.\r\n */\r\n style?: Record<string, string | number>;\r\n}\r\n\r\nexport interface RobotToastOptions {\r\n /** The message text to display in the toast */\r\n message: string;\r\n\r\n /** Auto-close duration in ms, or false to disable. Default: 5000 */\r\n autoClose?: boolean | number;\r\n\r\n /** Position of the toast on screen. Default: 'bottom-right' */\r\n position?: ToastPosition;\r\n\r\n /** Toast type/style. Default: 'default' */\r\n type?: ToastType;\r\n\r\n /** Visual theme. Default: 'light' */\r\n theme?: ToastTheme;\r\n\r\n /**\r\n * Inline style object to apply directly to the message box element.\r\n * This allows runtime customization of colors, fonts, backgrounds, etc.\r\n * Example: { color: 'red', backgroundColor: 'blue' }\r\n * This takes precedence over className for conflicting properties.\r\n */\r\n style?: Record<string, string | number>;\r\n\r\n /** Typing speed in ms per character. 0 = instant. Default: 30 */\r\n typeSpeed?: number;\r\n\r\n /**\r\n * Robot image source. Opt-in — nothing is shown unless you ask for one.\r\n * Pass one of:\r\n * - Omit (or pass `undefined` / `''` / `'none'`) to hide the robot entirely.\r\n * - `'default'` to render the built-in inline SVG (no network fetch).\r\n * - A data URL from `robot-toast/robots` (tree-shakeable, recommended):\r\n * import { wave } from 'robot-toast/robots';\r\n * toast({ message: 'Hi', robotVariant: wave });\r\n * - A path to an image file (svg/png/jpg/jpeg/gif/webp).\r\n * Unrecognized values are treated as \"hidden\" rather than rendered.\r\n */\r\n robotVariant?: string;\r\n\r\n /** Hide the countdown progress bar. Default: false */\r\n hideProgressBar?: boolean;\r\n\r\n /** Pause the auto-close countdown when the window loses focus. Default: true */\r\n pauseOnFocusLoss?: boolean;\r\n\r\n /** Allow the user to drag the toast around the screen. Default: true */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Position the robot near the screen edge (true) or away from it (false).\r\n * - true: robot appears between screen edge and message bubble\r\n * - false: message bubble appears between screen edge and robot\r\n * The position is automatically determined by the toast position and this setting.\r\n * Default: true\r\n */\r\n nearScreen?: boolean;\r\n\r\n /** Pause the auto-close countdown while the cursor is over the toast. Default: true */\r\n pauseOnHover?: boolean;\r\n\r\n /**\r\n * Maximum number of toasts visible simultaneously.\r\n * Excess toasts are queued and shown as soon as a slot opens.\r\n * 0 = unlimited (queue still works, all show in parallel). Default: 0\r\n */\r\n limit?: number;\r\n\r\n /** Stack newest toasts on top of older ones. Default: false */\r\n newestOnTop?: boolean;\r\n\r\n /** Right-to-left layout (message on the right, robot on the left). Default: false */\r\n rtl?: boolean;\r\n\r\n /** Entry / exit transition style. Default: 'bounce' */\r\n transition?: TransitionType;\r\n\r\n /**\r\n * Inline buttons to render inside the toast (e.g. Undo, Retry, Cancel).\r\n * Rendered in array order. Each click fires the button's `onClick` and\r\n * then closes the toast automatically.\r\n */\r\n buttons?: ToastButton[];\r\n\r\n /** Called when the toast finishes its enter animation and is fully visible. */\r\n onOpen?: () => void;\r\n\r\n /** Called after the toast has fully exited the screen. */\r\n onClose?: () => void;\r\n}\r\n\r\n/** Internal representation of a queued toast item */\r\nexport interface ToastQueueItem {\r\n options: RobotToastOptions;\r\n id: number;\r\n}\r\n\r\nexport interface RobotToastAPI {\r\n /** Show a toast notification – queued automatically when limit is reached */\r\n show: (options: RobotToastOptions) => number;\r\n /** Immediately close all visible toasts and clear the queue */\r\n closeAll: () => void;\r\n /** Close a specific toast by the id returned from show() */\r\n closeById: (id: number) => void;\r\n /** Get the RobotToastManager instance */\r\n getInstance: () => RobotToastInstance;\r\n}\r\n\r\nexport interface RobotToastInstance {\r\n show: (options: RobotToastOptions) => number;\r\n closeAll: () => void;\r\n closeById: (id: number) => void;\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n __robotToastLoaded?: boolean;\r\n __robotToastUtilsLoaded?: boolean;\r\n RobotToast?: RobotToastAPI;\r\n RobotToastUtils?: {\r\n showRobotToast: (options: RobotToastOptions) => Promise<number>;\r\n closeAllRobotToasts: () => Promise<void>;\r\n closeRobotToastById: (id: number) => Promise<void>;\r\n getRobotToastInstance: () => Promise<RobotToastAPI>;\r\n ensureRobotToastReady: (timeout?: number) => Promise<RobotToastAPI>;\r\n };\r\n }\r\n}","/**\r\n * robot-toast v2\r\n * A lightweight, framework-agnostic toast notification library\r\n * with an animated robot character, multi-toast queue, and smooth drag.\r\n *\r\n * ── Basic usage ──────────────────────────────────────────────────────────────\r\n * import { toast } from 'robot-toast';\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', position: 'top-right', type: 'success' });\r\n *\r\n * ── Typed shorthands ─────────────────────────────────────────────────────────\r\n * toast.success('Saved!');\r\n * toast.error('Something went wrong');\r\n * toast.info('Did you know…');\r\n * toast.warning('Check your input');\r\n *\r\n * ── Class / manager ──────────────────────────────────────────────────────────\r\n * import { RobotToast } from 'robot-toast';\r\n * const manager = RobotToast.getInstance();\r\n * const id = manager.show({ message: 'Hi!' });\r\n * manager.closeById(id);\r\n */\r\n\r\nimport RobotToastManager from './toast';\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\nimport './styles-injector'; // Auto-inject styles\r\n\r\n// ─── Core show function ────────────────────────────────────────────────────\r\n\r\ntype ToastInput = string | RobotToastOptions;\r\n\r\nfunction normalise(input: ToastInput): RobotToastOptions {\r\n return typeof input === 'string' ? { message: input } : input;\r\n}\r\n\r\n/**\r\n * Show a toast notification.\r\n * Accepts either a plain string or a full options object.\r\n * Returns the toast id (useful for closeById).\r\n *\r\n * @example\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', type: 'success', position: 'top-right' });\r\n */\r\nfunction toast(input: ToastInput): number {\r\n if (typeof window === 'undefined') return -1;\r\n return RobotToastManager.getInstance().show(normalise(input));\r\n}\r\n\r\n// ── Typed shorthand helpers ───────────────────────────────────────────────────\r\ntoast.success = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'success' });\r\n\r\ntoast.error = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'error' });\r\n\r\ntoast.info = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'info' });\r\n\r\ntoast.warning = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'warning' });\r\n\r\n// ── Close helpers ─────────────────────────────────────────────────────────────\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\ntoast.closeAll = (): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeAll();\r\n};\r\n\r\n/**\r\n * Close a specific toast by the id returned from toast() / toast.show().\r\n */\r\ntoast.closeById = (id: number): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeById(id);\r\n};\r\n\r\n// ── Promise helper ────────────────────────────────────────────────────────────\r\n\r\ntype PromiseMessage<T, E = unknown> = {\r\n loading: string | Partial<RobotToastOptions>;\r\n success: string | ((value: T) => string | Partial<RobotToastOptions>);\r\n error: string | ((err: E) => string | Partial<RobotToastOptions>);\r\n};\r\n\r\n/**\r\n * Attach a toast lifecycle to a promise.\r\n * Shows a persistent `loading` toast; on settlement, closes it and shows a\r\n * `success` or `error` toast. Returns the original promise unchanged so\r\n * callers can still await / chain it.\r\n *\r\n * @example\r\n * toast.promise(fetch('/api/save'), {\r\n * loading: 'Saving…',\r\n * success: 'Saved!',\r\n * error: 'Save failed',\r\n * });\r\n */\r\ntoast.promise = <T, E = unknown>(\r\n promise: Promise<T>,\r\n messages: PromiseMessage<T, E>,\r\n): Promise<T> => {\r\n if (typeof window === 'undefined') return promise;\r\n\r\n const loadingOpts: RobotToastOptions =\r\n typeof messages.loading === 'string'\r\n ? { message: messages.loading }\r\n : { message: '', ...messages.loading };\r\n\r\n const loadingId = toast({\r\n autoClose: false,\r\n hideProgressBar: true,\r\n ...loadingOpts,\r\n // Override typeSpeed for loading so the text appears immediately — a loading\r\n // state that types letter-by-letter feels wrong.\r\n typeSpeed: loadingOpts.typeSpeed ?? 0,\r\n });\r\n\r\n const resolveOptions = (\r\n v: string | Partial<RobotToastOptions>,\r\n fallbackType: RobotToastOptions['type'],\r\n ): RobotToastOptions => {\r\n const base = typeof v === 'string' ? { message: v } : { message: '', ...v };\r\n return { type: fallbackType, ...base };\r\n };\r\n\r\n return promise.then(\r\n (value) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.success === 'function'\r\n ? messages.success(value)\r\n : messages.success;\r\n toast(resolveOptions(next, 'success'));\r\n return value;\r\n },\r\n (err: E) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.error === 'function'\r\n ? messages.error(err)\r\n : messages.error;\r\n toast(resolveOptions(next, 'error'));\r\n throw err;\r\n },\r\n );\r\n};\r\n\r\nexport { toast };\r\n\r\n// ─── Class export ──────────────────────────────────────────────────────────\r\n\r\nexport { default as RobotToast, RobotToastManager } from './toast';\r\n\r\n// ─── Utilities ─────────────────────────────────────────────────────────────\r\n\r\nexport {\r\n ensureRobotToastReady,\r\n showRobotToast,\r\n closeAllRobotToasts,\r\n getRobotToastInstance,\r\n} from './utils';\r\n\r\n// ─── Types ─────────────────────────────────────────────────────────────────\r\n\r\nexport type {\r\n RobotToastOptions,\r\n RobotToastAPI,\r\n RobotToastInstance,\r\n ToastQueueItem,\r\n ToastPosition,\r\n ToastType,\r\n ToastTheme,\r\n TransitionType,\r\n} from './types';\r\n\r\nexport {\r\n TOAST_POSITIONS,\r\n TOAST_TYPES,\r\n TOAST_THEMES,\r\n TOAST_TRANSITIONS,\r\n} from './types';\r\n\r\n// ─── Global registration (for script-tag / CDN usage) ──────────────────────\r\n\r\nfunction registerGlobal(): void {\r\n if (typeof window === 'undefined') return;\r\n if (window.__robotToastLoaded) return;\r\n window.__robotToastLoaded = true;\r\n\r\n const api: RobotToastAPI = {\r\n show: (options: RobotToastOptions) => RobotToastManager.getInstance().show(options),\r\n closeAll: () => RobotToastManager.getInstance().closeAll(),\r\n closeById: (id: number) => RobotToastManager.getInstance().closeById(id),\r\n getInstance: () => RobotToastManager.getInstance(),\r\n };\r\n\r\n window.RobotToast = api;\r\n}\r\n\r\nregisterGlobal();"]}
|
|
1
|
+
{"version":3,"sources":["../src/styles-injector.ts","../src/toast.ts","../src/utils.ts","../src/types.ts","../src/index.ts"],"names":["_InjectStyles","styleId","styles","styleElement","InjectStyles","styles_injector_default","_nextId","nextId","STACK_GAP","chunkButtons","buttons","n","rows","i","ToastItem","id","options","onRemove","resolved","positionIsLeft","initialSide","fn","bottomPx","w","classes","assertive","v","ALLOWED_EXTS","ext","r","kind","img","box","key","value","camelCaseKey","g","closeBtn","e","body","text","footer","rowBtns","row","btn","pContainer","pBar","button","el","camelKey","err","rtl","robotHidden","messageHidden","showMessage","msgEnterClass","onMsgEntered","side","transitionSuffix","enterClass","onRobotEntered","done","afterMsg","exitClass","afterRobot","message","typeSpeed","index","active","tick","elapsed","onEnter","onLeave","onBlur","onFocus","onPointerDown","rect","onPointerMove","maxX","maxY","newLeft","newTop","onPointerUp","_e","currentTop","midX","centerX","snapToLeft","newRobotSide","finalLeft","finalTop","robotOnLeft","snapClass","_RobotToastManager","limit","toast","t","q","doneId","next","groups","pos","list","offset","RobotToastManager","ensureRobotToastReady","timeout","resolve","reject","startTime","interval","showRobotToast","closeAllRobotToasts","getRobotToastInstance","TOAST_POSITIONS","TOAST_TYPES","TOAST_THEMES","TOAST_TRANSITIONS","normalise","input","promise","messages","loadingOpts","loadingId","resolveOptions","fallbackType","base","registerGlobal","api"],"mappings":"AAKA,IAAMA,CAAAA,CAAN,MAAMA,CAAa,CAGjB,WAAA,EAAc,CACR,OAAO,QAAA,CAAa,GAAA,EAAeA,CAAAA,CAAa,QAAA,GAIpDA,CAAAA,CAAa,SAAW,IAAA,CACxB,IAAA,CAAK,SAAA,EAAU,EACjB,CAEQ,SAAA,EAAkB,CACxB,IAAMC,CAAAA,CAAU,oBAAA,CAGhB,GAAI,QAAA,CAAS,cAAA,CAAeA,CAAO,CAAA,CACjC,OAGF,IAAMC,CAAAA,CAAS;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CAkvBTC,CAAAA,CAAe,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","file":"index.mjs","sourcesContent":["/**\r\n * Style injection for RobotToast\r\n * Injects all required CSS into the document when instantiated\r\n */\r\n\r\nclass InjectStyles {\r\n private static injected = false;\r\n\r\n constructor() {\r\n if (typeof document === 'undefined' || InjectStyles.injected) {\r\n return;\r\n }\r\n\r\n InjectStyles.injected = true;\r\n this.injectCSS();\r\n }\r\n\r\n private injectCSS(): void {\r\n const styleId = 'robot-toast-styles';\r\n\r\n // Check if styles already exist\r\n if (document.getElementById(styleId)) {\r\n return;\r\n }\r\n\r\n const styles = `\r\n/* RobotToast v2 - CSS Styles */\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* WRAPPER - Fixed positioning container for each toast */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-wrapper {\r\n position: fixed;\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n opacity: 0;\r\n z-index: 99999;\r\n pointer-events: auto;\r\n touch-action: none;\r\n -webkit-user-select: none;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-visible {\r\n opacity: 1;\r\n}\r\n\r\n/* Position presets */\r\n.robot-toast-wrapper.robot-toast-top-right {\r\n top: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-left {\r\n top: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-top-center {\r\n top: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-right {\r\n bottom: 20px;\r\n right: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-left {\r\n bottom: 20px;\r\n left: 20px;\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-bottom-center {\r\n bottom: 20px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n flex-direction: row;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-rtl {\r\n direction: rtl;\r\n}\r\n\r\n.robot-toast-wrapper.robot-toast-dragging .robot-toast-message {\r\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ROBOT - The animated character */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-robot {\r\n width: 65px;\r\n height: 70px;\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0;\r\n}\r\n\r\n.robot-toast-robot img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-left {\r\n animation: robot-enter-left 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right {\r\n animation: robot-enter-right 0.7s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left {\r\n animation: robot-exit-left 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right {\r\n animation: robot-exit-right 0.5s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-idle {\r\n opacity: 1;\r\n animation: robot-idle 2s ease-in-out infinite;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-left {\r\n animation: robot-snap-left 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-snap-right {\r\n animation: robot-snap-right 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* MESSAGE BOX - Toast content container */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-message {\r\n position: relative;\r\n width: fit-content;\r\n min-width: 120px;\r\n max-width: min(400px, calc(100vw - 120px));\r\n /*\r\n * IMPORTANT: no padding on the outer box. Each section (.robot-toast-body,\r\n * .robot-toast-footer, .robot-toast-progress-container) owns its own\r\n * spacing, so optional sections can disappear without us having to tweak\r\n * margins / paddings anywhere else.\r\n */\r\n padding: 0;\r\n border-radius: 8px;\r\n margin: 0;\r\n opacity: 0;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\r\n user-select: none;\r\n cursor: default;\r\n box-sizing: border-box;\r\n}\r\n\r\n.robot-toast-message.robot-toast-empty {\r\n display: none;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light {\r\n background: #ffffff;\r\n color: #333333;\r\n border: 1px solid #e0e0e0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark {\r\n background: #2d2d2d;\r\n color: #f0f0f0;\r\n border: 1px solid #444444;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored {\r\n color: #ffffff;\r\n}\r\n\r\n/* Type-specific colors for colored theme */\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-default {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-info {\r\n background: linear-gradient(135deg, #2193b0 0%, #6dd5ed 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-success {\r\n background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-warning {\r\n background: linear-gradient(135deg, #fb6e3b 0%, #f5a623 100%);\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-colored.robot-toast-type-error {\r\n background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);\r\n}\r\n\r\n/* Light theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-info {\r\n border-left: 4px solid #2193b0;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-success {\r\n border-left: 4px solid #11998e;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-warning {\r\n border-left: 4px solid #fb6e3b;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-light.robot-toast-type-error {\r\n border-left: 4px solid #eb3349;\r\n}\r\n\r\n/* Dark theme type-specific colors */\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-info {\r\n border-left: 4px solid #6dd5ed;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-success {\r\n border-left: 4px solid #38ef7d;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-warning {\r\n border-left: 4px solid #f5a623;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark.robot-toast-type-error {\r\n border-left: 4px solid #f45c43;\r\n}\r\n\r\n.robot-toast-message.message-enter {\r\n animation: message-enter 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-message.message-exit {\r\n animation: message-exit 0.3s ease-in forwards;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* CLOSE BUTTON */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-close {\r\n position: absolute;\r\n top: 4px;\r\n right: 4px;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n line-height: 1;\r\n font-family: Arial, sans-serif;\r\n cursor: pointer;\r\n opacity: 0.6;\r\n transition: opacity 0.2s;\r\n padding: 0;\r\n width: 28px;\r\n height: 28px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: currentColor;\r\n}\r\n\r\n.robot-toast-close:hover {\r\n opacity: 1;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* DRAG HINT */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-drag-hint {\r\n position: absolute;\r\n left: 8px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 3px;\r\n opacity: 0.4;\r\n}\r\n\r\n.robot-toast-drag-hint span {\r\n display: block;\r\n width: 4px;\r\n height: 4px;\r\n border-radius: 50%;\r\n background: currentColor;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* BODY — the message zone. Always present, always owns its own padding. */\r\n/* Right padding leaves clear room for the absolute close button. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-body {\r\n padding: 10px 40px 10px 14px;\r\n}\r\n\r\n.robot-toast-text {\r\n font-size: 14px;\r\n line-height: 1.5;\r\n word-break: break-word;\r\n white-space: pre-wrap;\r\n font-weight: 500;\r\n min-width: 0;\r\n min-height: 1.5em;\r\n /* No padding-bottom here — body's padding-bottom handles spacing toward\r\n whichever section follows (footer, progress bar, or nothing). */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* FOOTER — the button zone. Rendered only when buttons.length > 0. */\r\n/* Owns its own bottom padding so there are no conditional margins anywhere. */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-footer {\r\n /*\r\n * Symmetric vertical padding (10px top + 10px bottom) — matches body so\r\n * the two sections feel like equally-weighted \"cards\" stacked inside the\r\n * toast. This is intentional even though it doubles the gap between text\r\n * and buttons (10 body-bottom + 10 footer-top = 20px); the visual balance\r\n * matters more than the gap-tightness.\r\n */\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n}\r\n\r\n/* A row inside the footer. data-count drives width distribution — pure CSS,\r\n * no JS-side layout code. */\r\n.robot-toast-row {\r\n display: flex;\r\n gap: 6px;\r\n align-items: center;\r\n}\r\n\r\n/* 1 button in its row → content-sized, left-aligned (flex default) */\r\n.robot-toast-row[data-count=\"1\"] .robot-toast-btn {\r\n /* nothing — intrinsic width, flex-start alignment */\r\n}\r\n\r\n/* 2 or 3 buttons in a row → equal shares, filling the row's width */\r\n.robot-toast-row[data-count=\"2\"] .robot-toast-btn,\r\n.robot-toast-row[data-count=\"3\"] .robot-toast-btn {\r\n flex: 1;\r\n min-width: 0; /* let long labels shrink without breaking the 50/50 split */\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* INLINE BUTTONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-btn {\r\n appearance: none;\r\n font: inherit;\r\n font-size: 12px;\r\n font-weight: 500;\r\n line-height: 1;\r\n padding: 6px 12px;\r\n border-radius: 5px;\r\n cursor: pointer;\r\n transition: background 0.15s ease, color 0.15s ease, transform 0.05s ease;\r\n white-space: nowrap;\r\n background: transparent;\r\n color: #52525b;\r\n border: 1px solid #e4e4e7;\r\n}\r\n.robot-toast-btn:hover { background: #f4f4f5; color: #18181b; }\r\n.robot-toast-btn:active { transform: scale(0.97); }\r\n\r\n/*\r\n * Solo CTA: when the toast has exactly one button, it's implicitly the\r\n * primary action. Render it filled/dark so it feels decisive (Undo / Retry\r\n * UX). A multi-button toast drops back to all-neutral — the caller picks a\r\n * primary via its own className.\r\n *\r\n * \"Exactly one button total\" = the single row has data-count=\"1\" AND is the\r\n * only row in the footer (covers the n=1 case; n=4 also has data-count rows\r\n * but they're paired, not only-child).\r\n */\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #18181b;\r\n color: #fafafa;\r\n border-color: #18181b;\r\n font-weight: 600;\r\n}\r\n.robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #000;\r\n border-color: #000;\r\n color: #fafafa;\r\n}\r\n\r\n/* Dark theme — inverted neutral */\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn {\r\n color: #a1a1aa;\r\n border-color: #3f3f46;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-btn:hover {\r\n background: #27272a;\r\n color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: #fafafa;\r\n color: #18181b;\r\n border-color: #fafafa;\r\n}\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #e4e4e7;\r\n border-color: #e4e4e7;\r\n color: #18181b;\r\n}\r\n\r\n/* Colored theme — translucent whites keep contrast on any gradient */\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn {\r\n color: rgba(255, 255, 255, 0.9);\r\n border-color: rgba(255, 255, 255, 0.35);\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-btn:hover {\r\n background: rgba(255, 255, 255, 0.15);\r\n color: #fff;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn {\r\n background: rgba(255, 255, 255, 0.95);\r\n color: #18181b;\r\n border-color: transparent;\r\n}\r\n.robot-toast-message.robot-toast-theme-colored .robot-toast-row[data-count=\"1\"]:only-child .robot-toast-btn:hover {\r\n background: #fff;\r\n color: #18181b;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* PROGRESS BAR */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n.robot-toast-progress-container {\r\n width: 100%;\r\n height: 3px;\r\n background: rgba(0, 0, 0, 0.1);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.robot-toast-message.robot-toast-theme-dark .robot-toast-progress-container {\r\n background: rgba(255, 255, 255, 0.15);\r\n}\r\n\r\n.robot-toast-progress-bar {\r\n height: 100%;\r\n background: currentColor;\r\n transform-origin: left;\r\n transform: scaleX(1); /* ← starts full */\r\n}\r\n\r\n.robot-toast-theme-light.robot-toast-type-success .robot-toast-progress-bar { background: #11998e; }\r\n.robot-toast-theme-light.robot-toast-type-error .robot-toast-progress-bar { background: #eb3349; }\r\n.robot-toast-theme-light.robot-toast-type-warning .robot-toast-progress-bar { background: #fb6e3b; }\r\n.robot-toast-theme-light.robot-toast-type-info .robot-toast-progress-bar { background: #2193b0; }\r\n\r\n/* Dark theme progress bar colors */\r\n.robot-toast-theme-dark.robot-toast-type-success .robot-toast-progress-bar { background: #38ef7d; }\r\n.robot-toast-theme-dark.robot-toast-type-error .robot-toast-progress-bar { background: #f45c43; }\r\n.robot-toast-theme-dark.robot-toast-type-warning .robot-toast-progress-bar { background: #f5a623; }\r\n.robot-toast-theme-dark.robot-toast-type-info .robot-toast-progress-bar { background: #6dd5ed; }\r\n\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-auto {\r\n animation: robot-progress-countdown linear forwards;\r\n opacity: 0.8;\r\n}\r\n\r\n.robot-toast-progress-bar.robot-toast-progress-paused {\r\n animation-play-state: paused !important;\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* ANIMATIONS */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n@keyframes robot-enter-left {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-enter-right {\r\n 0% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n 40% { opacity: 1; transform: translateY(10px) scaleY(0.85) scaleX(1.1); }\r\n 65% { transform: translateY(-6px) scaleY(1.05) scaleX(0.97); }\r\n 85% { transform: translateY(2px) scaleY(0.98); }\r\n 100% { opacity: 1; transform: translateY(0) scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-left {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(-30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n@keyframes robot-exit-right {\r\n 0% { opacity: 1; transform: scale(1); }\r\n 20% { transform: scaleY(0.85) scaleX(1.1) translateY(5px); }\r\n 100% { opacity: 0; transform: translateY(-80px) translateX(30px) scaleY(1.1) scaleX(0.9); }\r\n}\r\n\r\n\r\n@keyframes robot-idle {\r\n 0%, 100% {\r\n transform: translateY(0);\r\n }\r\n 50% {\r\n transform: translateY(-4px);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-left {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes robot-snap-right {\r\n from {\r\n transform: scaleX(0.8);\r\n }\r\n to {\r\n transform: scaleX(1);\r\n }\r\n}\r\n\r\n@keyframes message-enter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n@keyframes message-exit {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n}\r\n\r\n@keyframes robot-progress-countdown {\r\n from { transform: scaleX(1); }\r\n to { transform: scaleX(0); }\r\n}\r\n\r\n/* Slide transition animations */\r\n.robot-toast-robot.robot-enter-left-slide {\r\n animation: robot-enter-left-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-slide {\r\n animation: robot-enter-right-slide 0.5s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-slide {\r\n animation: robot-exit-left-slide 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-slide {\r\n animation: robot-exit-right-slide 0.4s ease-in forwards;\r\n}\r\n\r\n/* Zoom transition animations */\r\n.robot-toast-robot.robot-enter-left-zoom,\r\n.robot-toast-robot.robot-enter-right-zoom {\r\n animation: robot-enter-zoom 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-zoom,\r\n.robot-toast-robot.robot-exit-right-zoom {\r\n animation: robot-exit-zoom 0.4s ease-in forwards;\r\n}\r\n\r\n/* Flip transition animations */\r\n.robot-toast-robot.robot-enter-left-flip {\r\n animation: robot-enter-left-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-enter-right-flip {\r\n animation: robot-enter-right-flip 0.6s ease-out forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-left-flip {\r\n animation: robot-exit-left-flip 0.4s ease-in forwards;\r\n}\r\n\r\n.robot-toast-robot.robot-exit-right-flip {\r\n animation: robot-exit-right-flip 0.4s ease-in forwards;\r\n}\r\n\r\n@keyframes robot-enter-left-slide {\r\n from { opacity: 0; transform: translateX(-60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-enter-right-slide {\r\n from { opacity: 0; transform: translateX(60px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n@keyframes robot-exit-left-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(-60px); }\r\n}\r\n\r\n@keyframes robot-exit-right-slide {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(60px); }\r\n}\r\n\r\n@keyframes robot-enter-zoom {\r\n from { opacity: 0; transform: scale(0.2); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n\r\n@keyframes robot-exit-zoom {\r\n from { opacity: 1; transform: scale(1); }\r\n to { opacity: 0; transform: scale(0.2); }\r\n}\r\n\r\n@keyframes robot-enter-left-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-enter-right-flip {\r\n from { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n to { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n}\r\n\r\n@keyframes robot-exit-left-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(90deg); }\r\n}\r\n\r\n@keyframes robot-exit-right-flip {\r\n from { opacity: 1; transform: perspective(600px) rotateY(0deg); }\r\n to { opacity: 0; transform: perspective(600px) rotateY(-90deg); }\r\n}\r\n\r\n/* message-enter variants */\r\n.robot-toast-message.message-enter-slide {\r\n animation: message-enter-slide 0.35s ease-out forwards;\r\n}\r\n.robot-toast-message.message-enter-zoom {\r\n animation: message-enter-zoom 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n.robot-toast-message.message-enter-flip {\r\n animation: message-enter-flip 0.4s ease-out forwards;\r\n}\r\n\r\n@keyframes message-enter-slide {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n@keyframes message-enter-zoom {\r\n from { opacity: 0; transform: scale(0.5); }\r\n to { opacity: 1; transform: scale(1); }\r\n}\r\n@keyframes message-enter-flip {\r\n from { opacity: 0; transform: perspective(400px) rotateX(-20deg); }\r\n to { opacity: 1; transform: perspective(400px) rotateX(0deg); }\r\n}\r\n\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n/* RESPONSIVE - Mobile / small-screen tweaks */\r\n/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */\r\n\r\n/*\r\n * Small-viewport tweaks. No !important / edge-to-edge override here — the\r\n * wrapper keeps its configured position preset and the message box stays\r\n * content-sized (just capped by max-width so it doesn't overflow). Drag\r\n * still works everywhere because no stylesheet rule competes with the\r\n * inline position the drag handler writes.\r\n */\r\n@media (max-width: 600px) {\r\n .robot-toast-wrapper {\r\n gap: 8px;\r\n max-width: calc(100vw - 24px);\r\n }\r\n\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-bottom-right { right: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-bottom-left { left: 12px; }\r\n .robot-toast-wrapper.robot-toast-top-right,\r\n .robot-toast-wrapper.robot-toast-top-left,\r\n .robot-toast-wrapper.robot-toast-top-center { top: 12px; }\r\n .robot-toast-wrapper.robot-toast-bottom-right,\r\n .robot-toast-wrapper.robot-toast-bottom-left,\r\n .robot-toast-wrapper.robot-toast-bottom-center { bottom: 12px; }\r\n\r\n .robot-toast-wrapper.robot-toast-top-center,\r\n .robot-toast-wrapper.robot-toast-bottom-center {\r\n width: calc(100vw - 24px);\r\n justify-content: center;\r\n }\r\n\r\n .robot-toast-robot {\r\n width: 48px;\r\n height: 52px;\r\n }\r\n\r\n .robot-toast-message {\r\n min-width: 100px;\r\n max-width: calc(100vw - 48px - 24px - 8px);\r\n font-size: 13px;\r\n /* padding stays 0 on the outer box; sections own their spacing */\r\n }\r\n\r\n .robot-toast-body {\r\n padding: 10px 36px 10px 12px;\r\n }\r\n\r\n .robot-toast-footer {\r\n /* Same symmetric vertical padding as body — equal section weight on mobile too */\r\n padding: 10px;\r\n }\r\n\r\n .robot-toast-text {\r\n font-size: 13px;\r\n }\r\n\r\n .robot-toast-close {\r\n width: 24px;\r\n height: 24px;\r\n font-size: 20px;\r\n }\r\n}\r\n\r\n@media (max-width: 360px) {\r\n .robot-toast-robot {\r\n width: 40px;\r\n height: 44px;\r\n }\r\n .robot-toast-message {\r\n max-width: calc(100vw - 40px - 20px - 8px);\r\n }\r\n}\r\n `;\r\n\r\n const styleElement = document.createElement('style');\r\n styleElement.id = styleId;\r\n styleElement.textContent = styles;\r\n document.head.appendChild(styleElement);\r\n }\r\n}\r\n\r\nexport default InjectStyles;\r\n","/**\r\n * RobotToast v2\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * • Multi-toast support with configurable limit + queue\r\n * • Each toast is a self-contained ToastItem instance – no shared mutable state\r\n * • Sequenced robot enter → message pop-in, message pop-out → robot exit\r\n * • Full XY drag with viewport clamping; on drop the robot snaps to the\r\n * nearest screen edge (left / right) with a personality animation\r\n * • Progress bar auto-animates for the countdown; pauses correctly on hover\r\n * and drag; resumes with exact remaining time\r\n * • All event listeners are tracked and fully removed on close\r\n * • SVG-only enforcement for custom robot images; always renders at fixed size\r\n * • SSR-safe (all DOM access is guarded by typeof window / document checks)\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n */\r\n\r\nimport type { RobotToastOptions, ToastQueueItem, ToastButton } from './types';\r\nimport InjectStyles from './styles-injector';\r\n\r\n// ─── Unique ID counter ────────────────────────────────────────────────────────\r\nlet _nextId = 1;\r\nfunction nextId(): number { return _nextId++; }\r\n\r\n// ─── Vertical offset step between stacked toasts (px) ────────────────────────\r\nconst STACK_GAP = 16;\r\n\r\n/**\r\n * Split N buttons into rows according to the layout spec:\r\n * 1→[1] 2→[2] 3→[3] 4→[2,2]\r\n * 5→[3,2] 6→[3,3] 7→[3,2,2] 8→[3,3,2] 9→[3,3,3]\r\n * 10→[3,3,2,2] 11→[3,3,3,2] 12→[3,3,3,3] …\r\n * Rule: fill rows of 3 from the top. If the tail would leave a single\r\n * lonely button, steal one from the previous row so the last two rows\r\n * balance as [2, 2].\r\n */\r\nfunction chunkButtons<T>(buttons: T[]): T[][] {\r\n const n = buttons.length;\r\n if (n === 0) return [];\r\n if (n <= 3) return [buttons.slice()];\r\n if (n === 4) return [buttons.slice(0, 2), buttons.slice(2)];\r\n\r\n const rows: T[][] = [];\r\n let i = 0;\r\n while (n - i > 4) {\r\n rows.push(buttons.slice(i, i + 3));\r\n i += 3;\r\n }\r\n const rem = n - i;\r\n if (rem === 4) {\r\n rows.push(buttons.slice(i, i + 2));\r\n rows.push(buttons.slice(i + 2));\r\n } else {\r\n rows.push(buttons.slice(i));\r\n }\r\n return rows;\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n ToastItem – one live toast on screen\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass ToastItem {\r\n readonly id: number;\r\n private options: {\r\n message: string;\r\n autoClose: boolean | number;\r\n position: NonNullable<RobotToastOptions['position']>;\r\n type: NonNullable<RobotToastOptions['type']>;\r\n theme: NonNullable<RobotToastOptions['theme']>;\r\n style?: Record<string, string | number>;\r\n typeSpeed: number;\r\n robotVariant: string;\r\n hideProgressBar: boolean;\r\n pauseOnFocusLoss: boolean;\r\n draggable: boolean;\r\n nearScreen: boolean;\r\n pauseOnHover: boolean;\r\n rtl: boolean;\r\n transition: NonNullable<RobotToastOptions['transition']>;\r\n buttons?: ToastButton[];\r\n onOpen?: () => void;\r\n onClose?: () => void;\r\n };\r\n\r\n // DOM refs\r\n private wrapper: HTMLDivElement;\r\n private robotEl: HTMLDivElement;\r\n private messageBox: HTMLDivElement;\r\n private progressBar: HTMLDivElement | null = null;\r\n private messageText: HTMLDivElement;\r\n\r\n // Timer state\r\n private autoCloseDuration: number; // ms; 0 = no auto-close\r\n private remainingTime: number; // ms left on the countdown\r\n private timerStart: number | null = null; // when the current timer was set\r\n private closeTimeout: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // Interaction state\r\n private isDragging = false;\r\n private dragOffsetX = 0;\r\n private dragOffsetY = 0;\r\n private dragWidth = 0;\r\n private dragHeight = 0;\r\n private currentRobotSide: 'left' | 'right';\r\n private isHovered = false;\r\n private isFocusLost = false;\r\n private isClosed = false;\r\n\r\n // Cleanup\r\n private cleanupFns: Array<() => void> = [];\r\n\r\n // Callback to notify the manager when this toast dies\r\n private onRemove: (id: number) => void;\r\n\r\n constructor(id: number, options: RobotToastOptions, onRemove: (id: number) => void) {\r\n this.id = id;\r\n this.onRemove = onRemove;\r\n\r\n // ── Resolve all options with defaults ──────────────────────────────────\r\n const resolved = {\r\n message: options.message,\r\n autoClose: options.autoClose ?? 5000,\r\n position: options.position ?? 'bottom-right',\r\n type: options.type ?? 'default',\r\n theme: options.theme ?? 'light',\r\n style: options.style,\r\n typeSpeed: options.typeSpeed ?? 30,\r\n robotVariant: options.robotVariant ?? '',\r\n hideProgressBar: options.hideProgressBar ?? false,\r\n pauseOnFocusLoss: options.pauseOnFocusLoss ?? true,\r\n draggable: options.draggable ?? true,\r\n nearScreen: options.nearScreen ?? true,\r\n pauseOnHover: options.pauseOnHover ?? true,\r\n rtl: options.rtl ?? false,\r\n transition: options.transition ?? 'bounce',\r\n buttons: options.buttons,\r\n onOpen: options.onOpen,\r\n onClose: options.onClose,\r\n };\r\n\r\n this.options = resolved;\r\n \r\n // Determine initial robot side based on nearScreen\r\n // nearScreen: true → robot near screen edge (position's side)\r\n // nearScreen: false → robot away from screen edge (opposite side)\r\n const positionIsLeft = resolved.position.includes('left');\r\n \r\n let initialSide: 'left' | 'right';\r\n if (resolved.nearScreen) {\r\n // Robot near edge: follow position\r\n initialSide = positionIsLeft ? 'left' : 'right';\r\n } else {\r\n // Robot away from edge: opposite of position\r\n initialSide = positionIsLeft ? 'right' : 'left';\r\n }\r\n this.currentRobotSide = initialSide;\r\n this.autoCloseDuration = typeof resolved.autoClose === 'number'\r\n ? resolved.autoClose\r\n : (resolved.autoClose ? 5000 : 0);\r\n this.remainingTime = this.autoCloseDuration;\r\n\r\n // ── Build DOM ──────────────────────────────────────────────────────────\r\n this.wrapper = this.buildWrapper();\r\n this.robotEl = this.buildRobot();\r\n this.messageBox = this.buildMessageBox();\r\n this.messageText = this.messageBox.querySelector('.robot-toast-text')!;\r\n this.progressBar = this.messageBox.querySelector('.robot-toast-progress-bar');\r\n\r\n // Empty message → hide message box entirely (only the robot shows)\r\n if (resolved.message === '') {\r\n this.messageBox.classList.add('robot-toast-empty');\r\n }\r\n\r\n this.assembleLayout();\r\n document.body.appendChild(this.wrapper);\r\n\r\n // ── Wire interactions ──────────────────────────────────────────────────\r\n if (resolved.draggable) this.initDrag();\r\n if (resolved.pauseOnFocusLoss) this.initFocusWatcher();\r\n if (resolved.pauseOnHover) this.initHoverWatcher();\r\n\r\n // ── Kick off the entrance sequence ─────────────────────────────────────\r\n requestAnimationFrame(() => this.playEntrance());\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n close(): void {\r\n if (this.isClosed) return;\r\n this.isClosed = true;\r\n\r\n this.cancelTimer();\r\n this.cleanupFns.forEach(fn => fn());\r\n this.cleanupFns = [];\r\n\r\n this.playExit(() => {\r\n if (this.wrapper.parentNode) {\r\n this.wrapper.parentNode.removeChild(this.wrapper);\r\n }\r\n this.options.onClose?.();\r\n this.onRemove(this.id);\r\n });\r\n }\r\n\r\n /** Shift this toast vertically by `delta` px (used by manager for stacking) */\r\n shiftVertical(bottomPx: number): void {\r\n const pos = this.options.position;\r\n if (pos.startsWith('bottom')) {\r\n this.wrapper.style.bottom = `${bottomPx}px`;\r\n } else {\r\n this.wrapper.style.top = `${bottomPx}px`;\r\n }\r\n }\r\n\r\n getWrapperHeight(): number {\r\n return this.wrapper.getBoundingClientRect().height || 90;\r\n }\r\n\r\n // ── DOM builders ───────────────────────────────────────────────────────────\r\n\r\n private buildWrapper(): HTMLDivElement {\r\n const w = document.createElement('div');\r\n const classes = ['robot-toast-wrapper', `robot-toast-${this.options.position}`];\r\n if (this.options.rtl) classes.push('robot-toast-rtl');\r\n w.className = classes.join(' ');\r\n\r\n // ARIA: error/warning are assertive (role=alert), everything else polite (role=status).\r\n const assertive = this.options.type === 'error' || this.options.type === 'warning';\r\n w.setAttribute('role', assertive ? 'alert' : 'status');\r\n w.setAttribute('aria-live', assertive ? 'assertive' : 'polite');\r\n w.setAttribute('aria-atomic', 'true');\r\n\r\n return w;\r\n }\r\n\r\n /**\r\n * Decides what a given `robotVariant` resolves to:\r\n * - `'hidden'` — not shown at all (omitted, '' empty, 'none' alias, or unusable string)\r\n * - `'default'` — built-in inline SVG\r\n * - `'image'` — external image source (data URL or file path)\r\n */\r\n private resolveVariant(): 'hidden' | 'default' | 'image' {\r\n const v = this.options.robotVariant;\r\n if (!v || v === 'none') return 'hidden';\r\n if (v === 'default') return 'default';\r\n const ALLOWED_EXTS = ['.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp'];\r\n const isDataUrl = v.startsWith('data:');\r\n const isAllowed = isDataUrl\r\n || ALLOWED_EXTS.some(ext => v.toLowerCase().endsWith(ext));\r\n return isAllowed ? 'image' : 'hidden';\r\n }\r\n\r\n private buildRobot(): HTMLDivElement {\r\n const r = document.createElement('div');\r\n r.className = 'robot-toast-robot';\r\n\r\n const kind = this.resolveVariant();\r\n\r\n if (kind === 'hidden') {\r\n r.style.display = 'none';\r\n return r;\r\n }\r\n\r\n if (kind === 'default') {\r\n r.innerHTML = this.getBuiltinSVG();\r\n return r;\r\n }\r\n\r\n // kind === 'image' — data URL or recognized path. Fall back to the\r\n // built-in SVG only if the image fails to load at runtime (the user\r\n // clearly intended a robot, so we don't want an empty slot).\r\n const img = document.createElement('img');\r\n img.src = this.options.robotVariant;\r\n img.alt = 'Robot';\r\n img.setAttribute('width', '65');\r\n img.setAttribute('height', '70');\r\n img.style.cssText = 'width:100%;height:100%;object-fit:contain;display:block;';\r\n img.onerror = () => { r.innerHTML = this.getBuiltinSVG(); };\r\n r.appendChild(img);\r\n return r;\r\n }\r\n\r\n private buildMessageBox(): HTMLDivElement {\r\n const box = document.createElement('div');\r\n const classes = [\r\n 'robot-toast-message',\r\n `robot-toast-type-${this.options.type}`,\r\n `robot-toast-theme-${this.options.theme}`,\r\n ].filter(Boolean);\r\n box.className = classes.join(' ');\r\n box.style.cursor = this.options.draggable ? 'grab' : 'default';\r\n\r\n // Apply inline styles if provided (takes precedence over theme colors)\r\n if (this.options.style) {\r\n Object.entries(this.options.style).forEach(([key, value]) => {\r\n const camelCaseKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (box.style as any)[camelCaseKey] = value;\r\n });\r\n }\r\n\r\n // ── Layout ────────────────────────────────────────────────────────────\r\n // Discrete sections, each owning its own spacing. The outer `box` has no\r\n // padding — bodyPad and footerPad live on the sections themselves, so\r\n // optional pieces (footer, progress bar) can appear/disappear without\r\n // us having to juggle conditional margins anywhere else.\r\n\r\n // Close button — absolute, top-right of the whole box (outside sections)\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'robot-toast-close';\r\n closeBtn.innerHTML = '×';\r\n closeBtn.title = 'Dismiss';\r\n closeBtn.type = 'button';\r\n closeBtn.setAttribute('aria-label', 'Dismiss notification');\r\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.close(); });\r\n box.appendChild(closeBtn);\r\n\r\n // Section 1 — body (message text). Always present.\r\n const body = document.createElement('div');\r\n body.className = 'robot-toast-body';\r\n const text = document.createElement('div');\r\n text.className = 'robot-toast-text';\r\n body.appendChild(text);\r\n box.appendChild(body);\r\n\r\n // Section 2 — footer (button rows). Rendered only when buttons exist.\r\n if (this.options.buttons && this.options.buttons.length > 0) {\r\n const footer = document.createElement('div');\r\n footer.className = 'robot-toast-footer';\r\n // Chunk into rows per the layout spec (1→[1] 4→[2,2] 5→[3,2] 7→[3,2,2] …)\r\n // then emit each row with `data-count` so CSS can pick the right split.\r\n const rows = chunkButtons(this.options.buttons);\r\n rows.forEach(rowBtns => {\r\n const row = document.createElement('div');\r\n row.className = 'robot-toast-row';\r\n row.setAttribute('data-count', String(rowBtns.length));\r\n rowBtns.forEach(btn => row.appendChild(this.buildButton(btn)));\r\n footer.appendChild(row);\r\n });\r\n box.appendChild(footer);\r\n }\r\n\r\n // Progress bar — unchanged, always last.\r\n const pContainer = document.createElement('div');\r\n pContainer.className = 'robot-toast-progress-container';\r\n if (this.options.hideProgressBar) pContainer.style.display = 'none';\r\n\r\n const pBar = document.createElement('div');\r\n pBar.className = 'robot-toast-progress-bar';\r\n\r\n pContainer.appendChild(pBar);\r\n box.appendChild(pContainer);\r\n\r\n return box;\r\n }\r\n\r\n private buildButton(button: ToastButton): HTMLButtonElement {\r\n const el = document.createElement('button');\r\n el.type = 'button';\r\n el.className = button.className\r\n ? `robot-toast-btn ${button.className}`\r\n : 'robot-toast-btn';\r\n el.textContent = button.label;\r\n\r\n // Inline style: same kebab → camel conversion the message-level `style`\r\n // option uses, so consumers can pass either form. Applied after className\r\n // so it takes precedence over class-based rules.\r\n if (button.style) {\r\n Object.entries(button.style).forEach(([key, value]) => {\r\n const camelKey = key.replace(/-([a-z])/g, g => g[1].toUpperCase());\r\n (el.style as unknown as Record<string, string | number>)[camelKey] = value;\r\n });\r\n }\r\n\r\n el.addEventListener('click', (e) => {\r\n // Stop the click from bubbling to drag / hover handlers on the wrapper.\r\n e.stopPropagation();\r\n // Fire the callback, then dismiss. If the callback throws we still\r\n // close — otherwise a bad handler strands the toast on screen.\r\n try {\r\n button.onClick(e);\r\n } catch (err) {\r\n console.error('[robot-toast] button onClick threw:', err);\r\n }\r\n this.close();\r\n });\r\n return el;\r\n }\r\n\r\n private assembleLayout(): void {\r\n const { rtl } = this.options;\r\n this.wrapper.innerHTML = '';\r\n\r\n // Decide order: rtl flips everything, robot side controls natural order\r\n const robotOnLeft = rtl ? this.currentRobotSide === 'right' : this.currentRobotSide === 'left';\r\n\r\n if (robotOnLeft) {\r\n this.wrapper.appendChild(this.robotEl);\r\n this.wrapper.appendChild(this.messageBox);\r\n } else {\r\n this.wrapper.appendChild(this.messageBox);\r\n this.wrapper.appendChild(this.robotEl);\r\n }\r\n }\r\n\r\n // ── Sequenced animations ───────────────────────────────────────────────────\r\n\r\n private playEntrance(): void {\r\n // Step 1 – wrapper becomes visible\r\n this.wrapper.classList.add('robot-toast-visible');\r\n\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const showMessage = () => {\r\n if (messageHidden) {\r\n // No text box – skip pop-in, still fire onOpen and start timer\r\n this.options.onOpen?.();\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n // Message pops in\r\n const msgEnterClass = this.options.transition === 'bounce'\r\n ? 'message-enter'\r\n : `message-enter-${this.options.transition}`;\r\n this.messageBox.classList.add(msgEnterClass);\r\n\r\n const onMsgEntered = () => {\r\n this.messageBox.removeEventListener('animationend', onMsgEntered);\r\n this.messageBox.classList.remove(msgEnterClass);\r\n this.messageBox.style.opacity = '1';\r\n this.messageBox.style.transform = 'none';\r\n\r\n this.options.onOpen?.();\r\n this.startTyping();\r\n };\r\n this.messageBox.addEventListener('animationend', onMsgEntered, { once: true });\r\n };\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot entrance, go straight to message\r\n showMessage();\r\n } else {\r\n // Step 2 – robot runs in with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const enterClass = `robot-enter-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(enterClass);\r\n\r\n const onRobotEntered = () => {\r\n this.robotEl.removeEventListener('animationend', onRobotEntered);\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(enterClass);\r\n this.robotEl.classList.add('robot-idle');\r\n showMessage();\r\n };\r\n this.robotEl.addEventListener('animationend', onRobotEntered, { once: true });\r\n }\r\n }\r\n\r\n private playExit(done: () => void): void {\r\n const robotHidden = this.resolveVariant() === 'hidden';\r\n const messageHidden = this.options.message === '';\r\n\r\n const afterMsg = () => {\r\n this.messageBox.removeEventListener('animationend', afterMsg);\r\n\r\n if (robotHidden) {\r\n // No robot – skip robot exit, just fade wrapper\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n } else {\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n\r\n // Step 2 – robot runs out with selected transition style\r\n const side = this.currentRobotSide === 'left' ? 'left' : 'right';\r\n const transitionSuffix = this.options.transition !== 'bounce' ? `-${this.options.transition}` : '';\r\n const exitClass = `robot-exit-${side}${transitionSuffix}`;\r\n this.robotEl.classList.add(exitClass);\r\n\r\n const afterRobot = () => {\r\n this.robotEl.removeEventListener('animationend', afterRobot);\r\n this.wrapper.classList.remove('robot-toast-visible');\r\n setTimeout(done, 260);\r\n };\r\n this.robotEl.addEventListener('animationend', afterRobot, { once: true });\r\n }\r\n };\r\n\r\n if (messageHidden) {\r\n // No text box – skip the collapse step entirely\r\n afterMsg();\r\n } else {\r\n this.messageBox.classList.add('message-exit');\r\n this.messageBox.addEventListener('animationend', afterMsg, { once: true });\r\n }\r\n }\r\n\r\n // ── Typing effect ──────────────────────────────────────────────────────────\r\n\r\n private startTyping(): void {\r\n const { message, typeSpeed } = this.options;\r\n const el = this.messageText;\r\n\r\n if (typeSpeed === 0) {\r\n // Instant – no animation\r\n el.textContent = message;\r\n this.afterTypingComplete();\r\n return;\r\n }\r\n\r\n let index = 0;\r\n let active = true;\r\n\r\n // Register cleanup so that if toast is closed mid-type the loop stops\r\n this.cleanupFns.push(() => { active = false; });\r\n\r\n const tick = () => {\r\n if (!active) return;\r\n if (index < message.length) {\r\n el.textContent += message.charAt(index++);\r\n setTimeout(tick, typeSpeed);\r\n } else {\r\n this.afterTypingComplete();\r\n }\r\n };\r\n tick();\r\n }\r\n\r\n private afterTypingComplete(): void {\r\n // Always start auto-progress-bar animation (unless hidden)\r\n if (this.autoCloseDuration > 0 && !this.options.hideProgressBar && this.progressBar) {\r\n this.progressBar.style.animationDuration = `${this.autoCloseDuration}ms`; // set duration FIRST\r\n void this.progressBar.offsetWidth; // flush\r\n this.progressBar.classList.add('robot-toast-progress-auto'); // THEN start\r\n if (this.isHovered || this.isFocusLost) {\r\n this.progressBar.classList.add('robot-toast-progress-paused');\r\n }\r\n }\r\n\r\n // Start the close timer unless something is currently pausing it\r\n if (!this.isHovered && !this.isFocusLost) {\r\n this.startTimer();\r\n }\r\n }\r\n\r\n // ── Timer management ───────────────────────────────────────────────────────\r\n\r\n private startTimer(): void {\r\n if (this.autoCloseDuration <= 0 || this.remainingTime <= 0) return;\r\n this.timerStart = Date.now();\r\n this.closeTimeout = setTimeout(() => this.close(), this.remainingTime);\r\n }\r\n\r\n private pauseTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n if (this.timerStart !== null) {\r\n const elapsed = Date.now() - this.timerStart;\r\n this.remainingTime = Math.max(0, this.remainingTime - elapsed);\r\n this.timerStart = null;\r\n }\r\n }\r\n this.progressBar?.classList.add('robot-toast-progress-paused');\r\n }\r\n\r\n private resumeTimer(): void {\r\n if (this.isHovered || this.isFocusLost || this.isDragging) return;\r\n this.progressBar?.classList.remove('robot-toast-progress-paused');\r\n this.startTimer();\r\n }\r\n\r\n private cancelTimer(): void {\r\n if (this.closeTimeout) {\r\n clearTimeout(this.closeTimeout);\r\n this.closeTimeout = null;\r\n }\r\n }\r\n\r\n // ── Hover watcher ──────────────────────────────────────────────────────────\r\n\r\n private initHoverWatcher(): void {\r\n const onEnter = () => {\r\n this.isHovered = true;\r\n this.pauseTimer();\r\n };\r\n const onLeave = () => {\r\n this.isHovered = false;\r\n this.resumeTimer();\r\n };\r\n this.wrapper.addEventListener('mouseenter', onEnter);\r\n this.wrapper.addEventListener('mouseleave', onLeave);\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('mouseenter', onEnter);\r\n this.wrapper.removeEventListener('mouseleave', onLeave);\r\n });\r\n }\r\n\r\n // ── Focus watcher ──────────────────────────────────────────────────────────\r\n\r\n private initFocusWatcher(): void {\r\n const onBlur = () => {\r\n this.isFocusLost = true;\r\n this.pauseTimer();\r\n };\r\n const onFocus = () => {\r\n this.isFocusLost = false;\r\n this.resumeTimer();\r\n };\r\n window.addEventListener('blur', onBlur);\r\n window.addEventListener('focus', onFocus);\r\n this.cleanupFns.push(() => {\r\n window.removeEventListener('blur', onBlur);\r\n window.removeEventListener('focus', onFocus);\r\n });\r\n }\r\n\r\n // ── Drag ──────────────────────────────────────────────────────────────────\r\n\r\n private initDrag(): void {\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Pointer events (covers both mouse & touch via pointer API) ──────────\r\n const onPointerDown = (e: PointerEvent) => {\r\n // Clicks / taps on the close button or any inline action button must\r\n // never initiate a drag — otherwise the user can't actually press them.\r\n if ((e.target as HTMLElement).closest(\r\n '.robot-toast-close, .robot-toast-btn'\r\n )) return;\r\n // Only primary button / first touch\r\n if (e.button !== undefined && e.button !== 0) return;\r\n\r\n e.preventDefault();\r\n this.isDragging = true;\r\n this.pauseTimer();\r\n\r\n // \"Detach\" the wrapper from its CSS-positioned slot by converting its\r\n // current visual position into explicit inline top/left values.\r\n const rect = this.wrapper.getBoundingClientRect();\r\n this.wrapper.classList.add('robot-toast-dragging');\r\n\r\n // Inline position so the wrapper sits exactly where it was\r\n this.wrapper.style.top = `${rect.top}px`;\r\n this.wrapper.style.left = `${rect.left}px`;\r\n this.wrapper.style.right = 'auto';\r\n this.wrapper.style.bottom = 'auto';\r\n this.wrapper.style.transform = 'none';\r\n\r\n // Cache size — width/height don't change during drag, so we avoid a\r\n // layout read on every pointermove (major mobile jank source).\r\n this.dragWidth = rect.width;\r\n this.dragHeight = rect.height;\r\n\r\n // Offset = where inside the wrapper the pointer grabbed\r\n this.dragOffsetX = e.clientX - rect.left;\r\n this.dragOffsetY = e.clientY - rect.top;\r\n\r\n this.messageBox.style.cursor = 'grabbing';\r\n this.wrapper.setPointerCapture(e.pointerId);\r\n };\r\n\r\n const onPointerMove = (e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n e.preventDefault();\r\n\r\n // Use cached width/height + live window dims — no layout flush.\r\n const maxX = window.innerWidth - this.dragWidth;\r\n const maxY = window.innerHeight - this.dragHeight;\r\n\r\n const newLeft = Math.max(0, Math.min(e.clientX - this.dragOffsetX, maxX));\r\n const newTop = Math.max(0, Math.min(e.clientY - this.dragOffsetY, maxY));\r\n\r\n this.wrapper.style.left = `${newLeft}px`;\r\n this.wrapper.style.top = `${newTop}px`;\r\n };\r\n\r\n const onPointerUp = (_e: PointerEvent) => {\r\n if (!this.isDragging) return;\r\n this.isDragging = false;\r\n this.wrapper.classList.remove('robot-toast-dragging');\r\n this.messageBox.style.cursor = 'grab';\r\n\r\n // ── Snap to nearest horizontal screen edge ────────────────────────────\r\n // One getBoundingClientRect() on drop is fine — it's a single layout\r\n // flush per release, not per frame. This is more robust than reading\r\n // inline style.left, which can lag the rendered position in edge cases\r\n // (parent transforms, pending animations, etc.).\r\n const rect = this.wrapper.getBoundingClientRect();\r\n const currentTop = rect.top;\r\n const midX = rect.left + rect.width / 2;\r\n const centerX = window.innerWidth / 2;\r\n\r\n // Determine which edge to snap to based on which half the center is in\r\n const snapToLeft = midX < centerX;\r\n\r\n // Determine robot side based on nearScreen setting\r\n const newRobotSide: 'left' | 'right' = this.options.nearScreen\r\n ? (snapToLeft ? 'left' : 'right')\r\n : (snapToLeft ? 'right' : 'left');\r\n\r\n // Determine final resting left position (20px margin from edge)\r\n const finalLeft = snapToLeft ? 20 : window.innerWidth - this.dragWidth - 20;\r\n const finalTop = Math.max(20, Math.min(currentTop, window.innerHeight - this.dragHeight - 20));\r\n\r\n // Re-enable transitions for the snap glide\r\n this.wrapper.style.transition =\r\n 'left 0.45s cubic-bezier(0.34,1.56,0.64,1), top 0.4s cubic-bezier(0.34,1.56,0.64,1)';\r\n this.wrapper.style.left = `${finalLeft}px`;\r\n this.wrapper.style.top = `${finalTop}px`;\r\n\r\n // Update robot side if it changed\r\n if (newRobotSide !== this.currentRobotSide) {\r\n this.currentRobotSide = newRobotSide;\r\n\r\n // Use CSS order to visually reorder (no DOM detach = no animation restart)\r\n const robotOnLeft = newRobotSide === 'left';\r\n this.robotEl.style.order = robotOnLeft ? '0' : '1';\r\n this.messageBox.style.order = robotOnLeft ? '1' : '0';\r\n\r\n // Snap animation\r\n const snapClass = newRobotSide === 'left' ? 'robot-snap-left' : 'robot-snap-right';\r\n this.robotEl.classList.remove('robot-idle', 'robot-snap-left', 'robot-snap-right');\r\n this.robotEl.classList.add(snapClass);\r\n this.robotEl.addEventListener('animationend', () => {\r\n this.robotEl.style.opacity = '1';\r\n this.robotEl.classList.remove(snapClass);\r\n this.robotEl.classList.add('robot-idle');\r\n }, { once: true });\r\n }\r\n const clearTransition = () => {\r\n this.wrapper.style.transition = '';\r\n };\r\n setTimeout(clearTransition, 500);\r\n\r\n // Resume the auto-close timer\r\n this.resumeTimer();\r\n };\r\n\r\n this.wrapper.addEventListener('pointerdown', onPointerDown);\r\n this.wrapper.addEventListener('pointermove', onPointerMove);\r\n this.wrapper.addEventListener('pointerup', onPointerUp);\r\n this.wrapper.addEventListener('pointercancel', onPointerUp);\r\n\r\n this.cleanupFns.push(() => {\r\n this.wrapper.removeEventListener('pointerdown', onPointerDown);\r\n this.wrapper.removeEventListener('pointermove', onPointerMove);\r\n this.wrapper.removeEventListener('pointerup', onPointerUp);\r\n this.wrapper.removeEventListener('pointercancel', onPointerUp);\r\n });\r\n }\r\n\r\n // ── Built-in robot SVG ─────────────────────────────────────────────────────\r\n\r\n private getBuiltinSVG(): string {\r\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 120\"\r\n width=\"100%\" height=\"100%\" role=\"img\" aria-label=\"Robot\">\r\n <defs>\r\n <linearGradient id=\"rtGrad${this.id}\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#E2F0FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#B8D8FF\"/>\r\n </linearGradient>\r\n <linearGradient id=\"rtAccent${this.id}\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <stop offset=\"0%\" stop-color=\"#7CB9FF\"/>\r\n <stop offset=\"100%\" stop-color=\"#4A90D9\"/>\r\n </linearGradient>\r\n </defs>\r\n <!-- Antenna -->\r\n <line x1=\"50\" y1=\"4\" x2=\"50\" y2=\"18\" stroke=\"#2B3A55\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\r\n <circle cx=\"50\" cy=\"4\" r=\"4\" fill=\"#FF6B6B\"/>\r\n <!-- Head -->\r\n <rect x=\"24\" y=\"18\" width=\"52\" height=\"40\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Eyes -->\r\n <circle cx=\"38\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"62\" cy=\"36\" r=\"6\" fill=\"#2B3A55\"/>\r\n <circle cx=\"40\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <circle cx=\"64\" cy=\"34\" r=\"2\" fill=\"#ffffff\"/>\r\n <!-- Mouth -->\r\n <path d=\"M 38 50 Q 50 58 62 50\" stroke=\"#2B3A55\" stroke-width=\"2\"\r\n fill=\"none\" stroke-linecap=\"round\"/>\r\n <!-- Neck -->\r\n <rect x=\"44\" y=\"58\" width=\"12\" height=\"8\" rx=\"3\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <!-- Body -->\r\n <rect x=\"22\" y=\"66\" width=\"56\" height=\"44\" rx=\"10\" ry=\"10\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Chest panel -->\r\n <rect x=\"34\" y=\"76\" width=\"32\" height=\"20\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <circle cx=\"42\" cy=\"86\" r=\"3\" fill=\"#FF6B6B\"/>\r\n <circle cx=\"50\" cy=\"86\" r=\"3\" fill=\"#FFD700\"/>\r\n <circle cx=\"58\" cy=\"86\" r=\"3\" fill=\"#6BFF8A\"/>\r\n <!-- Arms -->\r\n <rect x=\"4\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <rect x=\"78\" y=\"68\" width=\"18\" height=\"30\" rx=\"9\"\r\n fill=\"url(#rtGrad${this.id})\" stroke=\"#2B3A55\" stroke-width=\"2\"/>\r\n <!-- Legs -->\r\n <rect x=\"30\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n <rect x=\"54\" y=\"110\" width=\"16\" height=\"10\" rx=\"5\"\r\n fill=\"url(#rtAccent${this.id})\" stroke=\"#2B3A55\" stroke-width=\"1.5\"/>\r\n </svg>`;\r\n }\r\n}\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n RobotToastManager – global singleton that owns all ToastItems\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\nclass RobotToastManager {\r\n private static _instance: RobotToastManager | null = null;\r\n\r\n private activeToasts: ToastItem[] = [];\r\n private queue: ToastQueueItem[] = [];\r\n private globalLimit = 0; // 0 = unlimited; overridden per-show call\r\n\r\n private constructor() {\r\n new InjectStyles();\r\n }\r\n\r\n static getInstance(): RobotToastManager {\r\n if (!RobotToastManager._instance) {\r\n RobotToastManager._instance = new RobotToastManager();\r\n }\r\n return RobotToastManager._instance;\r\n }\r\n\r\n // ── Public API ─────────────────────────────────────────────────────────────\r\n\r\n show(options: RobotToastOptions): number {\r\n if (typeof document === 'undefined') return -1;\r\n\r\n const id = nextId();\r\n const limit = options.limit ?? this.globalLimit;\r\n\r\n if (limit > 0 && this.activeToasts.length >= limit) {\r\n // Queue it for later\r\n this.queue.push({ options, id });\r\n return id;\r\n }\r\n\r\n this.spawnToast(options, id);\r\n return id;\r\n }\r\n\r\n closeAll(): void {\r\n this.queue = [];\r\n [...this.activeToasts].forEach(t => t.close());\r\n }\r\n\r\n closeById(id: number): void {\r\n const toast = this.activeToasts.find(t => t.id === id);\r\n if (toast) toast.close();\r\n\r\n // Also remove from queue if it hasn't spawned yet\r\n this.queue = this.queue.filter(q => q.id !== id);\r\n }\r\n\r\n // ── Internal ───────────────────────────────────────────────────────────────\r\n\r\n private spawnToast(options: RobotToastOptions, id: number): void {\r\n const toast = new ToastItem(id, options, (doneId) => this.handleRemoved(doneId));\r\n const newestOnTop = options.newestOnTop ?? false;\r\n\r\n if (newestOnTop) {\r\n this.activeToasts.unshift(toast);\r\n } else {\r\n this.activeToasts.push(toast);\r\n }\r\n\r\n this.restack();\r\n }\r\n\r\n private handleRemoved(id: number): void {\r\n this.activeToasts = this.activeToasts.filter(t => t.id !== id);\r\n this.restack();\r\n\r\n // Dequeue next if any\r\n if (this.queue.length > 0) {\r\n const next = this.queue.shift()!;\r\n // Small delay so the stack reflows are visible\r\n setTimeout(() => this.spawnToast(next.options, next.id), 120);\r\n }\r\n }\r\n\r\n /**\r\n * Recalculate the vertical position of every active toast so they stack\r\n * neatly without overlap. Works for both top-* and bottom-* positions.\r\n */\r\n private restack(): void {\r\n // Group by position string\r\n const groups: Record<string, ToastItem[]> = {};\r\n this.activeToasts.forEach(t => {\r\n const pos = (t as any).options.position as string;\r\n if (!groups[pos]) groups[pos] = [];\r\n groups[pos].push(t);\r\n });\r\n\r\n Object.keys(groups).forEach(pos => {\r\n const list = groups[pos];\r\n let offset = 20; // initial edge margin px\r\n\r\n list.forEach((toast) => {\r\n toast.shiftVertical(offset);\r\n offset += toast.getWrapperHeight() + STACK_GAP;\r\n });\r\n });\r\n }\r\n}\r\n\r\nexport { RobotToastManager as default, RobotToastManager };","/**\r\n * RobotToast Utilities v2\r\n * Helper functions for safer access to the RobotToast API.\r\n * Handles async readiness checks, SSR guards, and error boundaries.\r\n * Useful when loading robot-toast via a CDN <script> tag.\r\n */\r\n\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\n\r\n/**\r\n * Wait for window.RobotToast to be available, up to `timeout` ms.\r\n * Resolves immediately if it is already loaded.\r\n * Useful when the library is loaded via a <script> tag and you need\r\n * to call it from another script that may execute first.\r\n */\r\nexport function ensureRobotToastReady(timeout = 5000): Promise<RobotToastAPI> {\r\n return new Promise((resolve, reject) => {\r\n if (typeof window === 'undefined') {\r\n reject(new Error('[RobotToast] Cannot run outside of a browser environment.'));\r\n return;\r\n }\r\n\r\n if (window.RobotToast) {\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n const interval = setInterval(() => {\r\n if (window.RobotToast) {\r\n clearInterval(interval);\r\n resolve(window.RobotToast);\r\n return;\r\n }\r\n if (Date.now() - startTime >= timeout) {\r\n clearInterval(interval);\r\n reject(new Error(`[RobotToast] Failed to load within ${timeout}ms.`));\r\n }\r\n }, 80);\r\n });\r\n}\r\n\r\n/**\r\n * Show a robot toast notification.\r\n * Waits for the library to be ready before showing.\r\n * Returns the toast id or -1 on failure.\r\n */\r\nexport async function showRobotToast(options: RobotToastOptions): Promise<number> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n return api.show(options);\r\n } catch (err) {\r\n console.error('[RobotToast] showRobotToast failed:', err);\r\n return -1;\r\n }\r\n}\r\n\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\nexport async function closeAllRobotToasts(): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeAll();\r\n } catch (err) {\r\n console.error('[RobotToast] closeAllRobotToasts failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Close a specific toast by the id returned from show().\r\n */\r\nexport async function closeRobotToastById(id: number): Promise<void> {\r\n try {\r\n const api = await ensureRobotToastReady();\r\n api.closeById(id);\r\n } catch (err) {\r\n console.error('[RobotToast] closeRobotToastById failed:', err);\r\n }\r\n}\r\n\r\n/**\r\n * Get the RobotToast API instance.\r\n */\r\nexport async function getRobotToastInstance(): Promise<RobotToastAPI> {\r\n return ensureRobotToastReady();\r\n}","/**\r\n * RobotToast Types & Constants\r\n * Type definitions and constant arrays for the robot toast notification library\r\n */\r\n\r\n/** Array of all valid toast positions */\r\nexport const TOAST_POSITIONS = [\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] as const;\r\n\r\n/** Array of all valid toast types */\r\nexport const TOAST_TYPES = ['default', 'info', 'success', 'warning', 'error'] as const;\r\n\r\n/** Array of all valid toast themes */\r\nexport const TOAST_THEMES = ['light', 'dark', 'colored'] as const;\r\n\r\n/** Array of all valid transition animations */\r\nexport const TOAST_TRANSITIONS = ['bounce', 'slide', 'zoom', 'flip'] as const;\r\n\r\n/** Type derived from TOAST_POSITIONS constant */\r\nexport type ToastPosition = typeof TOAST_POSITIONS[number];\r\n\r\n/** Type derived from TOAST_TYPES constant */\r\nexport type ToastType = typeof TOAST_TYPES[number];\r\n\r\n/** Type derived from TOAST_THEMES constant */\r\nexport type ToastTheme = typeof TOAST_THEMES[number];\r\n\r\n/** Type derived from TOAST_TRANSITIONS constant */\r\nexport type TransitionType = typeof TOAST_TRANSITIONS[number];\r\n\r\n/**\r\n * A button rendered inside the toast. Pass an array of these as `buttons`\r\n * to add inline CTAs like \"Undo\" / \"Retry\" / \"Cancel\":\r\n *\r\n * toast({\r\n * message: 'File deleted',\r\n * buttons: [\r\n * { label: 'Undo', onClick: () => restore() },\r\n * ],\r\n * });\r\n *\r\n * Buttons render in array order. Clicking any of them fires its `onClick`\r\n * and then closes the toast. Visual hierarchy is up to you — pass a custom\r\n * `className` to override the default neutral style (e.g. to mark the\r\n * primary CTA as filled/bold and a secondary as muted).\r\n */\r\nexport interface ToastButton {\r\n /** Visible button text. Keep it short (1–2 words). */\r\n label: string;\r\n /** Fired before the toast closes. Receives the click event. */\r\n onClick: (event: MouseEvent) => void;\r\n /**\r\n * Optional CSS class(es) appended to the button element. Use this when you\r\n * have a stylesheet rule like `.my-primary { background: black; color: white }`\r\n * defined elsewhere in your app and want to apply it to this button.\r\n */\r\n className?: string;\r\n /**\r\n * Optional inline styles applied directly to the button element. Use this\r\n * when you don't want to add a CSS rule to your stylesheet — pass an object\r\n * of camelCased properties (or kebab-case keys; both work):\r\n *\r\n * style: { background: 'black', color: 'white', borderRadius: '8px' }\r\n *\r\n * Takes precedence over className-based rules and over the default neutral\r\n * (and solo-CTA) button styles.\r\n */\r\n style?: Record<string, string | number>;\r\n}\r\n\r\nexport interface RobotToastOptions {\r\n /** The message text to display in the toast */\r\n message: string;\r\n\r\n /** Auto-close duration in ms, or false to disable. Default: 5000 */\r\n autoClose?: boolean | number;\r\n\r\n /** Position of the toast on screen. Default: 'bottom-right' */\r\n position?: ToastPosition;\r\n\r\n /** Toast type/style. Default: 'default' */\r\n type?: ToastType;\r\n\r\n /** Visual theme. Default: 'light' */\r\n theme?: ToastTheme;\r\n\r\n /**\r\n * Inline style object to apply directly to the message box element.\r\n * This allows runtime customization of colors, fonts, backgrounds, etc.\r\n * Example: { color: 'red', backgroundColor: 'blue' }\r\n * This takes precedence over className for conflicting properties.\r\n */\r\n style?: Record<string, string | number>;\r\n\r\n /** Typing speed in ms per character. 0 = instant. Default: 30 */\r\n typeSpeed?: number;\r\n\r\n /**\r\n * Robot image source. Opt-in — nothing is shown unless you ask for one.\r\n * Pass one of:\r\n * - Omit (or pass `undefined` / `''` / `'none'`) to hide the robot entirely.\r\n * - `'default'` to render the built-in inline SVG (no network fetch).\r\n * - A data URL from `robot-toast/robots` (tree-shakeable, recommended):\r\n * import { wave } from 'robot-toast/robots';\r\n * toast({ message: 'Hi', robotVariant: wave });\r\n * - A path to an image file (svg/png/jpg/jpeg/gif/webp).\r\n * Unrecognized values are treated as \"hidden\" rather than rendered.\r\n */\r\n robotVariant?: string;\r\n\r\n /** Hide the countdown progress bar. Default: false */\r\n hideProgressBar?: boolean;\r\n\r\n /** Pause the auto-close countdown when the window loses focus. Default: true */\r\n pauseOnFocusLoss?: boolean;\r\n\r\n /** Allow the user to drag the toast around the screen. Default: true */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Position the robot near the screen edge (true) or away from it (false).\r\n * - true: robot appears between screen edge and message bubble\r\n * - false: message bubble appears between screen edge and robot\r\n * The position is automatically determined by the toast position and this setting.\r\n * Default: true\r\n */\r\n nearScreen?: boolean;\r\n\r\n /** Pause the auto-close countdown while the cursor is over the toast. Default: true */\r\n pauseOnHover?: boolean;\r\n\r\n /**\r\n * Maximum number of toasts visible simultaneously.\r\n * Excess toasts are queued and shown as soon as a slot opens.\r\n * 0 = unlimited (queue still works, all show in parallel). Default: 0\r\n */\r\n limit?: number;\r\n\r\n /** Stack newest toasts on top of older ones. Default: false */\r\n newestOnTop?: boolean;\r\n\r\n /** Right-to-left layout (message on the right, robot on the left). Default: false */\r\n rtl?: boolean;\r\n\r\n /** Entry / exit transition style. Default: 'bounce' */\r\n transition?: TransitionType;\r\n\r\n /**\r\n * Inline buttons to render inside the toast (e.g. Undo, Retry, Cancel).\r\n * Rendered in array order. Each click fires the button's `onClick` and\r\n * then closes the toast automatically.\r\n */\r\n buttons?: ToastButton[];\r\n\r\n /** Called when the toast finishes its enter animation and is fully visible. */\r\n onOpen?: () => void;\r\n\r\n /** Called after the toast has fully exited the screen. */\r\n onClose?: () => void;\r\n}\r\n\r\n/** Internal representation of a queued toast item */\r\nexport interface ToastQueueItem {\r\n options: RobotToastOptions;\r\n id: number;\r\n}\r\n\r\nexport interface RobotToastAPI {\r\n /** Show a toast notification – queued automatically when limit is reached */\r\n show: (options: RobotToastOptions) => number;\r\n /** Immediately close all visible toasts and clear the queue */\r\n closeAll: () => void;\r\n /** Close a specific toast by the id returned from show() */\r\n closeById: (id: number) => void;\r\n /** Get the RobotToastManager instance */\r\n getInstance: () => RobotToastInstance;\r\n}\r\n\r\nexport interface RobotToastInstance {\r\n show: (options: RobotToastOptions) => number;\r\n closeAll: () => void;\r\n closeById: (id: number) => void;\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n __robotToastLoaded?: boolean;\r\n __robotToastUtilsLoaded?: boolean;\r\n RobotToast?: RobotToastAPI;\r\n RobotToastUtils?: {\r\n showRobotToast: (options: RobotToastOptions) => Promise<number>;\r\n closeAllRobotToasts: () => Promise<void>;\r\n closeRobotToastById: (id: number) => Promise<void>;\r\n getRobotToastInstance: () => Promise<RobotToastAPI>;\r\n ensureRobotToastReady: (timeout?: number) => Promise<RobotToastAPI>;\r\n };\r\n }\r\n}","/**\r\n * robot-toast v2\r\n * A lightweight, framework-agnostic toast notification library\r\n * with an animated robot character, multi-toast queue, and smooth drag.\r\n *\r\n * ── Basic usage ──────────────────────────────────────────────────────────────\r\n * import { toast } from 'robot-toast';\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', position: 'top-right', type: 'success' });\r\n *\r\n * ── Typed shorthands ─────────────────────────────────────────────────────────\r\n * toast.success('Saved!');\r\n * toast.error('Something went wrong');\r\n * toast.info('Did you know…');\r\n * toast.warning('Check your input');\r\n *\r\n * ── Class / manager ──────────────────────────────────────────────────────────\r\n * import { RobotToast } from 'robot-toast';\r\n * const manager = RobotToast.getInstance();\r\n * const id = manager.show({ message: 'Hi!' });\r\n * manager.closeById(id);\r\n */\r\n\r\nimport RobotToastManager from './toast';\r\nimport type { RobotToastOptions, RobotToastAPI } from './types';\r\nimport './styles-injector'; // Auto-inject styles\r\n\r\n// ─── Core show function ────────────────────────────────────────────────────\r\n\r\ntype ToastInput = string | RobotToastOptions;\r\n\r\nfunction normalise(input: ToastInput): RobotToastOptions {\r\n return typeof input === 'string' ? { message: input } : input;\r\n}\r\n\r\n/**\r\n * Show a toast notification.\r\n * Accepts either a plain string or a full options object.\r\n * Returns the toast id (useful for closeById).\r\n *\r\n * @example\r\n * toast('Hello 🤖');\r\n * toast({ message: 'Hello!', type: 'success', position: 'top-right' });\r\n */\r\nfunction toast(input: ToastInput): number {\r\n if (typeof window === 'undefined') return -1;\r\n return RobotToastManager.getInstance().show(normalise(input));\r\n}\r\n\r\n// ── Typed shorthand helpers ───────────────────────────────────────────────────\r\ntoast.success = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'success' });\r\n\r\ntoast.error = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'error' });\r\n\r\ntoast.info = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'info' });\r\n\r\ntoast.warning = (input: ToastInput): number =>\r\n toast({ ...normalise(input), type: 'warning' });\r\n\r\n// ── Close helpers ─────────────────────────────────────────────────────────────\r\n/**\r\n * Close all visible toasts and clear the queue.\r\n */\r\ntoast.closeAll = (): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeAll();\r\n};\r\n\r\n/**\r\n * Close a specific toast by the id returned from toast() / toast.show().\r\n */\r\ntoast.closeById = (id: number): void => {\r\n if (typeof window === 'undefined') return;\r\n RobotToastManager.getInstance().closeById(id);\r\n};\r\n\r\n// ── Promise helper ────────────────────────────────────────────────────────────\r\n\r\ntype PromiseMessage<T, E = unknown> = {\r\n loading: string | Partial<RobotToastOptions>;\r\n success: string | ((value: T) => string | Partial<RobotToastOptions>);\r\n error: string | ((err: E) => string | Partial<RobotToastOptions>);\r\n};\r\n\r\n/**\r\n * Attach a toast lifecycle to a promise.\r\n * Shows a persistent `loading` toast; on settlement, closes it and shows a\r\n * `success` or `error` toast. Returns the original promise unchanged so\r\n * callers can still await / chain it.\r\n *\r\n * @example\r\n * toast.promise(fetch('/api/save'), {\r\n * loading: 'Saving…',\r\n * success: 'Saved!',\r\n * error: 'Save failed',\r\n * });\r\n */\r\ntoast.promise = <T, E = unknown>(\r\n promise: Promise<T>,\r\n messages: PromiseMessage<T, E>,\r\n): Promise<T> => {\r\n if (typeof window === 'undefined') return promise;\r\n\r\n const loadingOpts: RobotToastOptions =\r\n typeof messages.loading === 'string'\r\n ? { message: messages.loading }\r\n : { message: '', ...messages.loading };\r\n\r\n const loadingId = toast({\r\n autoClose: false,\r\n hideProgressBar: true,\r\n ...loadingOpts,\r\n // Override typeSpeed for loading so the text appears immediately — a loading\r\n // state that types letter-by-letter feels wrong.\r\n typeSpeed: loadingOpts.typeSpeed ?? 0,\r\n });\r\n\r\n const resolveOptions = (\r\n v: string | Partial<RobotToastOptions>,\r\n fallbackType: RobotToastOptions['type'],\r\n ): RobotToastOptions => {\r\n const base = typeof v === 'string' ? { message: v } : { message: '', ...v };\r\n return { type: fallbackType, ...base };\r\n };\r\n\r\n return promise.then(\r\n (value) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.success === 'function'\r\n ? messages.success(value)\r\n : messages.success;\r\n toast(resolveOptions(next, 'success'));\r\n return value;\r\n },\r\n (err: E) => {\r\n toast.closeById(loadingId);\r\n const next = typeof messages.error === 'function'\r\n ? messages.error(err)\r\n : messages.error;\r\n toast(resolveOptions(next, 'error'));\r\n throw err;\r\n },\r\n );\r\n};\r\n\r\nexport { toast };\r\n\r\n// ─── Class export ──────────────────────────────────────────────────────────\r\n\r\nexport { default as RobotToast, RobotToastManager } from './toast';\r\n\r\n// ─── Utilities ─────────────────────────────────────────────────────────────\r\n\r\nexport {\r\n ensureRobotToastReady,\r\n showRobotToast,\r\n closeAllRobotToasts,\r\n getRobotToastInstance,\r\n} from './utils';\r\n\r\n// ─── Types ─────────────────────────────────────────────────────────────────\r\n\r\nexport type {\r\n RobotToastOptions,\r\n RobotToastAPI,\r\n RobotToastInstance,\r\n ToastQueueItem,\r\n ToastPosition,\r\n ToastType,\r\n ToastTheme,\r\n TransitionType,\r\n} from './types';\r\n\r\nexport {\r\n TOAST_POSITIONS,\r\n TOAST_TYPES,\r\n TOAST_THEMES,\r\n TOAST_TRANSITIONS,\r\n} from './types';\r\n\r\n// ─── Global registration (for script-tag / CDN usage) ──────────────────────\r\n\r\nfunction registerGlobal(): void {\r\n if (typeof window === 'undefined') return;\r\n if (window.__robotToastLoaded) return;\r\n window.__robotToastLoaded = true;\r\n\r\n const api: RobotToastAPI = {\r\n show: (options: RobotToastOptions) => RobotToastManager.getInstance().show(options),\r\n closeAll: () => RobotToastManager.getInstance().closeAll(),\r\n closeById: (id: number) => RobotToastManager.getInstance().closeById(id),\r\n getInstance: () => RobotToastManager.getInstance(),\r\n };\r\n\r\n window.RobotToast = api;\r\n}\r\n\r\nregisterGlobal();"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "robot-toast",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "A lightweight, framework-agnostic toast notification library with an animated robot character. Tree-shakeable robots, draggable with swipe-to-dismiss, toast.promise(), and an optional React hook.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|