sonner-wc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/constants.ts", "../src/icons.ts", "../src/registry.ts", "../src/styles.ts", "../src/sonner-toast.ts", "../src/sonner-toaster.ts", "../src/toast.ts", "../src/index.ts"],
4
+ "sourcesContent": [
5
+ "export const VISIBLE_TOASTS_AMOUNT = 3;\nexport const VIEWPORT_OFFSET = '24px';\nexport const MOBILE_VIEWPORT_OFFSET = '16px';\nexport const TOAST_LIFETIME = 4000;\nexport const TOAST_WIDTH = 356;\nexport const GAP = 14;\nexport const SWIPE_THRESHOLD = 45;\nexport const SWIPE_VELOCITY_THRESHOLD = 0.11;\nexport const TIME_BEFORE_UNMOUNT = 200;\nexport const DEFAULT_HOTKEY: readonly string[] = ['altKey', 'KeyT'];\n",
6
+ "import type { ToastType } from './types.js';\n\nexport const SUCCESS_ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" height=\"20\" width=\"20\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\" clip-rule=\"evenodd\"/></svg>';\n\nexport const WARNING_ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" height=\"20\" width=\"20\"><path fill-rule=\"evenodd\" d=\"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z\" clip-rule=\"evenodd\"/></svg>';\n\nexport const INFO_ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" height=\"20\" width=\"20\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\" clip-rule=\"evenodd\"/></svg>';\n\nexport const ERROR_ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" height=\"20\" width=\"20\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\"/></svg>';\n\nexport const CLOSE_ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg>';\n\nconst SPINNER_BARS = Array.from(\n { length: 12 },\n () => '<div class=\"sonner-loading-bar\"></div>',\n).join('');\nexport const LOADING_SPINNER =\n '<div class=\"sonner-loading-wrapper\" data-visible=\"true\"><div class=\"sonner-spinner\">' +\n SPINNER_BARS +\n '</div></div>';\n\nexport function getTypeIcon(type: ToastType): string | null {\n switch (type) {\n case 'success':\n return SUCCESS_ICON;\n case 'info':\n return INFO_ICON;\n case 'warning':\n return WARNING_ICON;\n case 'error':\n return ERROR_ICON;\n case 'loading':\n // The spinner is rendered inside the shadow DOM (it needs the shadow's CSS\n // for its per-bar animation). #applyType handles the loading branch directly.\n return null;\n default:\n return null;\n }\n}\n",
7
+ "import type { SonnerToastElement, SonnerToasterElement } from './types.js';\n\n/** Tracks toasts and toasters by id so the toast() helper can find and update them\n * across multiple toasters and from anywhere in the module. */\n\nconst toastsById = new Map<string | number, SonnerToastElement>();\nconst toasters = new Set<SonnerToasterElement>();\n\nlet counter = 1;\n\nexport function nextToastId(): number {\n return counter++;\n}\n\nexport function registerToast(el: SonnerToastElement): void {\n toastsById.set(el.toastId, el);\n}\n\nexport function unregisterToast(el: SonnerToastElement): void {\n const current = toastsById.get(el.toastId);\n if (current === el) toastsById.delete(el.toastId);\n}\n\nexport function getToast(id: string | number): SonnerToastElement | undefined {\n return toastsById.get(id);\n}\n\nexport function registerToaster(el: SonnerToasterElement): void {\n toasters.add(el);\n}\n\nexport function unregisterToaster(el: SonnerToasterElement): void {\n toasters.delete(el);\n}\n\n/** Find a toaster element to host a new toast. Prefer the most-recently-connected one. */\nexport function defaultToaster(): SonnerToasterElement | undefined {\n let last: SonnerToasterElement | undefined;\n for (const t of toasters) last = t;\n return last;\n}\n\nexport function allToasters(): readonly SonnerToasterElement[] {\n return Array.from(toasters);\n}\n\nexport function dismissAllToasts(): void {\n for (const t of toasters) t.dismissAll();\n}\n",
8
+ "/**\n * Stylesheets shared across both custom elements via adoptedStyleSheets.\n *\n * CSS lives in plain `.css` files under `./styles/` so editors give full\n * language support (highlighting, autocomplete, Prettier). Bun's bundler\n * inlines the file contents as strings via the `with { type: 'text' }`\n * import attribute; we then wrap each in a CSSStyleSheet at runtime.\n *\n * Two scopes:\n * - toaster.css: positioning, theme palettes, dir-based vars (cascades into\n * child shadow trees via inherited custom properties).\n * - toast.css: per-toast layout, animations, swipe, rich colors (reads\n * the inherited theme vars set by the toaster).\n */\n\nimport toasterCss from './styles/toaster.css' with { type: 'text' };\nimport toastCss from './styles/toast.css' with { type: 'text' };\n\nlet toasterSheet: CSSStyleSheet | null = null;\nlet toastSheet: CSSStyleSheet | null = null;\n\nexport function getToasterSheet(): CSSStyleSheet {\n if (!toasterSheet) {\n toasterSheet = new CSSStyleSheet();\n toasterSheet.replaceSync(toasterCss);\n }\n return toasterSheet;\n}\n\nexport function getToastSheet(): CSSStyleSheet {\n if (!toastSheet) {\n toastSheet = new CSSStyleSheet();\n toastSheet.replaceSync(toastCss);\n }\n return toastSheet;\n}\n",
9
+ "import {\n TOAST_LIFETIME,\n TIME_BEFORE_UNMOUNT,\n SWIPE_THRESHOLD,\n SWIPE_VELOCITY_THRESHOLD,\n} from './constants.js';\nimport { CLOSE_ICON, getTypeIcon } from './icons.js';\nimport { registerToast, unregisterToast } from './registry.js';\nimport { getToastSheet } from './styles.js';\nimport type {\n SonnerToastElement,\n SonnerToasterElement,\n SwipeDirection,\n ToastAction,\n ToastContent,\n ToastOptions,\n ToastType,\n} from './types.js';\n\n// SSR-safe: when imported in Node without a DOM, fall back to a no-op base class.\n// The element won't function server-side but the import won't crash.\nconst HTMLElementCtor: typeof HTMLElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as unknown as typeof HTMLElement);\n\ntype PauseReason = 'hover-self' | 'focus-self' | 'doc-hidden' | 'toaster';\n\nfunction isUrgentType(type: ToastType): boolean {\n return type === 'error' || type === 'warning';\n}\n\nfunction setContent(host: HTMLElement, slotName: string, value: ToastContent | undefined): void {\n // Remove prior light DOM child(ren) with this slot name.\n for (const child of Array.from(host.children)) {\n if (child.getAttribute('slot') === slotName) host.removeChild(child);\n }\n if (value == null || value === '') return;\n const resolved = typeof value === 'function' ? value() : value;\n if (resolved instanceof Node) {\n if (resolved instanceof Element) resolved.setAttribute('slot', slotName);\n host.appendChild(resolved);\n } else {\n const span = document.createElement('span');\n span.setAttribute('slot', slotName);\n span.textContent = String(resolved);\n host.appendChild(span);\n }\n}\n\nfunction setButtonSlot(\n host: HTMLElement,\n slotName: 'action' | 'cancel',\n value: ToastAction | HTMLElement | undefined,\n defaultCloseHandler: () => void,\n): void {\n for (const child of Array.from(host.children)) {\n if (child.getAttribute('slot') === slotName) host.removeChild(child);\n }\n if (!value) return;\n if (value instanceof HTMLElement) {\n value.setAttribute('slot', slotName);\n host.appendChild(value);\n return;\n }\n const btn = document.createElement('button');\n btn.setAttribute('slot', slotName);\n btn.setAttribute('type', 'button');\n if (slotName === 'cancel') btn.setAttribute('data-cancel', '');\n else btn.setAttribute('data-action', '');\n btn.textContent = value.label;\n btn.addEventListener('click', (e) => {\n value.onClick?.(e as MouseEvent);\n if ((e as MouseEvent).defaultPrevented && slotName === 'action') return;\n defaultCloseHandler();\n });\n host.appendChild(btn);\n}\n\nconst SPINNER_BARS_HTML = Array.from(\n { length: 12 },\n () => '<div class=\"sonner-loading-bar\"></div>',\n).join('');\n\nconst SHADOW_TEMPLATE = `\n <div data-frame part=\"frame\">\n <button type=\"button\" data-close-button part=\"close-button\" hidden aria-label=\"Close toast\"></button>\n <div data-icon part=\"icon\">\n <slot name=\"icon\"></slot>\n <div class=\"sonner-loading-wrapper\" aria-hidden=\"true\">\n <div class=\"sonner-spinner\">${SPINNER_BARS_HTML}</div>\n </div>\n </div>\n <div data-content part=\"content\">\n <div data-title part=\"title\"><slot name=\"title\"></slot></div>\n <div data-description part=\"description\"><slot name=\"description\"></slot></div>\n </div>\n <slot name=\"cancel\"></slot>\n <slot name=\"action\"></slot>\n <slot part=\"custom\"></slot>\n </div>\n`;\n\nexport class SonnerToast extends HTMLElementCtor implements SonnerToastElement {\n static get observedAttributes() {\n return ['type', 'duration', 'dismissible', 'position', 'close-button', 'rich-colors', 'invert'];\n }\n\n toastId: string | number = 0;\n\n #shadow: ShadowRoot;\n #closeBtn!: HTMLButtonElement;\n #iconWrap!: HTMLDivElement;\n #titleWrap!: HTMLDivElement;\n #descWrap!: HTMLDivElement;\n\n #duration: number | null = null;\n #remainingTime = TOAST_LIFETIME;\n #timeoutId: ReturnType<typeof setTimeout> | null = null;\n #timerStartedAt = 0;\n #pauseReasons = new Set<PauseReason>();\n\n #pointerStart: { x: number; y: number } | null = null;\n #dragStartTime = 0;\n #swipeDirection: 'x' | 'y' | null = null;\n #swipeDirections: SwipeDirection[] | null = null;\n\n #mounted = false;\n #removed = false;\n #pendingRemoval = false;\n\n #onDismiss: ToastOptions['onDismiss'];\n #onAutoClose: ToastOptions['onAutoClose'];\n #closeButtonAriaLabel: string | null = null;\n /** Element that had focus immediately before focus first entered this toast.\n * Used to restore focus when the toast is dismissed while focused. */\n #prevFocus: Element | null = null;\n\n constructor() {\n super();\n this.#shadow = this.attachShadow({ mode: 'open' });\n this.#shadow.adoptedStyleSheets = [getToastSheet()];\n const tpl = document.createElement('template');\n tpl.innerHTML = SHADOW_TEMPLATE;\n this.#shadow.appendChild(tpl.content.cloneNode(true));\n this.#closeBtn = this.#shadow.querySelector('[data-close-button]') as HTMLButtonElement;\n this.#iconWrap = this.#shadow.querySelector('[data-icon]') as HTMLDivElement;\n this.#titleWrap = this.#shadow.querySelector('[data-title]') as HTMLDivElement;\n this.#descWrap = this.#shadow.querySelector('[data-description]') as HTMLDivElement;\n this.#closeBtn.innerHTML = CLOSE_ICON;\n this.#closeBtn.addEventListener('click', () => this.dismiss());\n\n // Reflect slot occupancy as host attributes so CSS can collapse empty wrappers.\n // (Browser support for `:host(:has(...))` is uneven; this is the reliable form.)\n const iconSlot = this.#shadow.querySelector('slot[name=\"icon\"]') as HTMLSlotElement;\n const descSlot = this.#shadow.querySelector('slot[name=\"description\"]') as HTMLSlotElement;\n iconSlot.addEventListener('slotchange', () => this.#reflectSlot('icon', iconSlot));\n descSlot.addEventListener('slotchange', () => this.#reflectSlot('description', descSlot));\n\n this.addEventListener('pointerdown', this.#onPointerDown);\n this.addEventListener('pointermove', this.#onPointerMove);\n this.addEventListener('pointerup', this.#onPointerUp);\n this.addEventListener('pointercancel', this.#onPointerUp);\n this.addEventListener('mouseenter', () => this.#pauseFor('hover-self'));\n this.addEventListener('mouseleave', () => this.#resumeFrom('hover-self'));\n this.addEventListener('focusin', (e: FocusEvent) => {\n this.#pauseFor('focus-self');\n // Capture the externally-focused element only once, on first entry.\n if (this.#prevFocus) return;\n const from = e.relatedTarget as Element | null;\n if (from && !this.contains(from)) this.#prevFocus = from;\n });\n this.addEventListener('focusout', () => this.#resumeFrom('focus-self'));\n this.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.#isDismissible()) {\n e.stopPropagation();\n this.dismiss();\n }\n });\n }\n\n connectedCallback() {\n if (!this.toastId) this.toastId = this.getAttribute('id') || 0;\n if (!this.hasAttribute('tabindex')) this.tabIndex = 0;\n this.#applyType(); // sets role/aria-live based on type (error/warning → alert/assertive)\n this.#applyDismissible();\n this.#applyPosition();\n this.#applyRichColors();\n this.#applyInvert();\n this.#applyCloseButton();\n this.setAttribute('data-sonner-toast', '');\n // aria-atomic ensures the whole toast re-announces when its contents\n // change (e.g. promise loading → success), instead of only the diff.\n if (!this.hasAttribute('aria-atomic')) this.setAttribute('aria-atomic', 'true');\n this.setAttribute('data-mounted', 'false');\n this.setAttribute('data-removed', 'false');\n this.setAttribute('data-swiping', 'false');\n this.setAttribute('data-swiped', 'false');\n this.setAttribute('data-swipe-out', 'false');\n if (!this.hasAttribute('data-styled')) this.setAttribute('data-styled', 'true');\n\n registerToast(this);\n\n document.addEventListener('visibilitychange', this.#onVisibilityChange);\n\n // Trigger mount on next frame so transitions kick in.\n requestAnimationFrame(() => {\n this.#mounted = true;\n this.setAttribute('data-mounted', 'true');\n this.dispatchEvent(\n new CustomEvent('sonner-toast-mounted', { bubbles: true, composed: true }),\n );\n this.#startTimer();\n });\n }\n\n disconnectedCallback() {\n if (this.#timeoutId) clearTimeout(this.#timeoutId);\n document.removeEventListener('visibilitychange', this.#onVisibilityChange);\n unregisterToast(this);\n }\n\n attributeChangedCallback(name: string, _old: string | null, _val: string | null) {\n if (!this.isConnected) return;\n switch (name) {\n case 'type':\n this.#applyType();\n break;\n case 'duration':\n this.#duration = this.#readDuration();\n this.#remainingTime = this.#duration ?? TOAST_LIFETIME;\n break;\n case 'dismissible':\n this.#applyDismissible();\n break;\n case 'position':\n this.#applyPosition();\n break;\n case 'close-button':\n this.#applyCloseButton();\n break;\n case 'rich-colors':\n this.#applyRichColors();\n break;\n case 'invert':\n this.#applyInvert();\n break;\n }\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n get toastType(): ToastType {\n return (this.getAttribute('type') as ToastType) || 'default';\n }\n\n /** Imperative dismiss — triggers exit animation, then removes from DOM. */\n dismiss(): void {\n if (this.#removed || this.#pendingRemoval) return;\n this.#pendingRemoval = true;\n this.#removed = true;\n this.setAttribute('data-removed', 'true');\n if (this.#timeoutId) clearTimeout(this.#timeoutId);\n this.dispatchEvent(\n new CustomEvent('sonner-toast-dismissed', { bubbles: true, composed: true }),\n );\n setTimeout(() => {\n this.#restoreFocusIfInside();\n this.#onDismiss?.(this);\n this.remove();\n }, TIME_BEFORE_UNMOUNT);\n }\n\n /** If focus is still inside this toast at dismissal time, move it back to\n * whatever was focused before focus first entered. Otherwise leave focus\n * alone — the user has moved on. */\n #restoreFocusIfInside(): void {\n if (!this.#prevFocus) return;\n const active = document.activeElement;\n if (!active || !this.contains(active)) return;\n const target = this.#prevFocus as HTMLElement;\n if (!target.isConnected || typeof target.focus !== 'function') return;\n target.focus();\n }\n\n /** Apply new content/options. Used by toast.promise() for loading→success/error transitions. */\n update(options: ToastOptions & { title?: ToastContent; type?: ToastType }): void {\n const typeChanged = options.type !== undefined && options.type !== this.toastType;\n const wasUrgent = isUrgentType(this.toastType);\n if (options.type !== undefined) this.setAttribute('type', options.type);\n let timerNeedsReset = false;\n if (options.duration !== undefined) {\n this.setAttribute('duration', String(options.duration));\n this.#duration = options.duration;\n this.#remainingTime = options.duration;\n timerNeedsReset = true;\n } else if (typeChanged) {\n // Type changed without an explicit new duration — discard prior override\n // (e.g. the `Infinity` we set when the toast started life as 'loading')\n // so #effectiveDuration falls back through the attribute or default.\n this.#duration = null;\n this.removeAttribute('duration');\n this.#remainingTime = 0;\n timerNeedsReset = true;\n }\n if (options.dismissible !== undefined) {\n if (options.dismissible) this.setAttribute('dismissible', '');\n else this.removeAttribute('dismissible');\n }\n if (options.position !== undefined) this.setAttribute('position', options.position);\n if (options.closeButton !== undefined) {\n if (options.closeButton) this.setAttribute('close-button', '');\n else this.removeAttribute('close-button');\n }\n if (options.richColors !== undefined) {\n if (options.richColors) this.setAttribute('rich-colors', '');\n else this.removeAttribute('rich-colors');\n }\n if (options.invert !== undefined) {\n if (options.invert) this.setAttribute('invert', '');\n else this.removeAttribute('invert');\n }\n if (options.icon !== undefined) this.setIcon(options.icon);\n if (options.title !== undefined) this.setTitle(options.title);\n if (options.description !== undefined) this.setDescription(options.description);\n if (options.action !== undefined) {\n setButtonSlot(this, 'action', options.action, () => this.dismiss());\n }\n if (options.cancel !== undefined) {\n setButtonSlot(this, 'cancel', options.cancel, () => this.dismiss());\n }\n if (options.className) this.className = options.className;\n if (options.testId !== undefined) this.setAttribute('data-testid', options.testId);\n if (options.closeButtonAriaLabel !== undefined) {\n this.#closeButtonAriaLabel = options.closeButtonAriaLabel || null;\n this.#applyCloseButtonAriaLabel();\n }\n if (options.onDismiss) this.#onDismiss = options.onDismiss;\n if (options.onAutoClose) this.#onAutoClose = options.onAutoClose;\n if (timerNeedsReset) this.#resetTimer();\n // Route urgent post-mount transitions (e.g. promise loading → error)\n // through the toaster's dedicated alert region. Re-evaluation of the\n // toast's own aria-live attribute is unreliable across screen readers;\n // the alert region is fresh and consistent.\n if (this.#mounted && typeChanged && !wasUrgent && isUrgentType(this.toastType)) {\n const titleEl = Array.from(this.children).find((c) => c.getAttribute('slot') === 'title');\n const text = titleEl?.textContent?.trim();\n if (text) {\n const toaster = this.closest('sonner-toaster') as SonnerToasterElement | null;\n toaster?.announceUrgent(text);\n }\n }\n this.dispatchEvent(new CustomEvent('sonner-toast-updated', { bubbles: true, composed: true }));\n }\n\n setTitle(value: ToastContent): void {\n setContent(this, 'title', value);\n this.#applyCloseButtonAriaLabel();\n }\n\n /** Apply the close button's aria-label: explicit override wins, otherwise\n * `Close: <title>` for disambiguation, falling back to `Close toast`. */\n #applyCloseButtonAriaLabel(): void {\n if (this.#closeButtonAriaLabel) {\n this.#closeBtn.setAttribute('aria-label', this.#closeButtonAriaLabel);\n return;\n }\n const titleEl = Array.from(this.children).find((c) => c.getAttribute('slot') === 'title');\n const text = titleEl?.textContent?.trim();\n this.#closeBtn.setAttribute('aria-label', text ? `Close: ${text}` : 'Close toast');\n }\n\n setDescription(value: ToastContent | undefined): void {\n setContent(this, 'description', value);\n }\n\n setIcon(value: Node | string | null | undefined): void {\n for (const child of Array.from(this.children)) {\n if (child.getAttribute('slot') === 'icon') this.removeChild(child);\n }\n if (value == null) return;\n if (value instanceof Node) {\n if (value instanceof Element) value.setAttribute('slot', 'icon');\n this.appendChild(value);\n } else {\n // Parse the HTML string and slot its first element directly — wrapping in a\n // <span> adds inline-baseline vertical wobble that breaks the icon's vertical\n // centering against the title.\n const tpl = document.createElement('template');\n tpl.innerHTML = value;\n const el = tpl.content.firstElementChild;\n if (el) {\n el.setAttribute('slot', 'icon');\n this.appendChild(el);\n }\n }\n }\n\n setHandlers(handlers: {\n onDismiss?: ToastOptions['onDismiss'];\n onAutoClose?: ToastOptions['onAutoClose'];\n }): void {\n this.#onDismiss = handlers.onDismiss;\n this.#onAutoClose = handlers.onAutoClose;\n }\n\n /** Called by the toaster to pause/resume this toast's auto-dismiss timer. */\n setPaused(paused: boolean): void {\n if (paused) this.#pauseFor('toaster');\n else this.#resumeFrom('toaster');\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n #reflectSlot(name: 'icon' | 'description', slot: HTMLSlotElement) {\n const has = slot.assignedNodes().length > 0;\n if (has) this.setAttribute(`data-has-${name}`, '');\n else this.removeAttribute(`data-has-${name}`);\n }\n\n #applyType() {\n const type = this.toastType;\n this.setAttribute('data-type', type);\n const urgent = isUrgentType(type);\n this.setAttribute('role', urgent ? 'alert' : 'status');\n this.setAttribute('aria-live', urgent ? 'assertive' : 'polite');\n if (type === 'loading') {\n this.setAttribute('data-promise', 'true');\n // The spinner lives in the shadow DOM (see SHADOW_TEMPLATE). CSS reveals it when\n // data-type='loading' and no user icon is slotted. Nothing to do here.\n // Clear any prior default icon left from a previous non-loading type.\n for (const c of Array.from(this.children)) {\n if (c.getAttribute('slot') === 'icon' && c.hasAttribute('data-sonner-default-icon'))\n this.removeChild(c);\n }\n } else {\n this.removeAttribute('data-promise');\n const hasUserIcon = Array.from(this.children).some((c) => {\n if (c.getAttribute('slot') !== 'icon') return false;\n // a previously-set default type icon is marked with data-sonner-default-icon\n return !c.hasAttribute('data-sonner-default-icon');\n });\n if (!hasUserIcon) {\n // Remove prior default icon\n for (const c of Array.from(this.children)) {\n if (c.getAttribute('slot') === 'icon' && c.hasAttribute('data-sonner-default-icon'))\n this.removeChild(c);\n }\n const builtin = getTypeIcon(type);\n if (builtin) {\n // Parse and slot the actual SVG/spinner element directly (no span wrapper).\n const tpl = document.createElement('template');\n tpl.innerHTML = builtin;\n const el = tpl.content.firstElementChild;\n if (el) {\n el.setAttribute('slot', 'icon');\n el.setAttribute('data-sonner-default-icon', '');\n this.appendChild(el);\n }\n }\n }\n }\n }\n\n #applyDismissible() {\n const dismissible = this.getAttribute('dismissible') !== 'false';\n this.setAttribute('data-dismissible', String(dismissible));\n }\n\n #applyPosition() {\n const pos = this.getAttribute('position');\n if (!pos) return;\n const [y, x] = pos.split('-');\n if (y) this.setAttribute('data-y-position', y);\n if (x) this.setAttribute('data-x-position', x);\n }\n\n #applyCloseButton() {\n const show = this.hasAttribute('close-button') && this.getAttribute('close-button') !== 'false';\n this.#closeBtn.hidden = !show;\n }\n\n #applyRichColors() {\n const rich = this.hasAttribute('rich-colors') && this.getAttribute('rich-colors') !== 'false';\n this.setAttribute('data-rich-colors', String(rich));\n }\n\n #applyInvert() {\n const invert = this.hasAttribute('invert') && this.getAttribute('invert') !== 'false';\n this.setAttribute('data-invert', String(invert));\n }\n\n #readDuration(): number | null {\n const raw = this.getAttribute('duration');\n if (raw == null) return null;\n if (raw === 'Infinity') return Infinity;\n const n = Number(raw);\n return Number.isFinite(n) || n === Infinity ? n : null;\n }\n\n #effectiveDuration(): number {\n const explicit = this.#duration ?? this.#readDuration();\n if (explicit !== null) return explicit;\n // No caller-provided duration: loading toasts wait forever (they're meant to be\n // resolved by toast.promise or an explicit dismiss); everything else uses the\n // default lifetime.\n if (this.toastType === 'loading') return Infinity;\n return TOAST_LIFETIME;\n }\n\n #startTimer() {\n if (!this.#mounted || this.#removed) return;\n if (this.#pauseReasons.size > 0) return;\n if (this.#timeoutId !== null) return;\n const dur = this.#effectiveDuration();\n if (dur === Infinity) return;\n this.#remainingTime = this.#remainingTime > 0 ? this.#remainingTime : dur;\n this.#timerStartedAt = Date.now();\n this.#timeoutId = setTimeout(() => {\n this.#timeoutId = null;\n this.#onAutoClose?.(this);\n this.dispatchEvent(\n new CustomEvent('sonner-toast-autoclosed', { bubbles: true, composed: true }),\n );\n this.dismiss();\n }, this.#remainingTime);\n }\n\n /** Add a pause reason. Pauses the timer if it wasn't already paused. */\n #pauseFor(reason: PauseReason) {\n const wasUnpaused = this.#pauseReasons.size === 0;\n this.#pauseReasons.add(reason);\n if (wasUnpaused && this.#timeoutId !== null) {\n clearTimeout(this.#timeoutId);\n this.#timeoutId = null;\n const elapsed = Date.now() - this.#timerStartedAt;\n this.#remainingTime = Math.max(0, this.#remainingTime - elapsed);\n }\n }\n\n /** Remove a pause reason. Resumes the timer when the last reason is cleared. */\n #resumeFrom(reason: PauseReason) {\n if (!this.#pauseReasons.delete(reason)) return;\n if (this.#pauseReasons.size === 0 && !this.#removed) this.#startTimer();\n }\n\n #resetTimer() {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n this.#timeoutId = null;\n }\n this.#remainingTime = this.#effectiveDuration();\n this.#startTimer();\n }\n\n #onVisibilityChange = () => {\n if (document.visibilityState === 'hidden') this.#pauseFor('doc-hidden');\n else this.#resumeFrom('doc-hidden');\n };\n\n // ─── Swipe ───────────────────────────────────────────────────────────────\n\n #isDismissible(): boolean {\n return this.getAttribute('dismissible') !== 'false';\n }\n\n #onPointerDown = (event: PointerEvent) => {\n if (event.button === 2) return;\n if (this.toastType === 'loading' || !this.#isDismissible()) return;\n // event.target is retargeted to the host as the event crosses the shadow boundary.\n // composedPath() preserves the actual element clicked inside shadow DOM, so we can\n // detect clicks on the close button or action/cancel buttons and skip swipe handling.\n const realTarget = event.composedPath()[0] as HTMLElement | undefined;\n if (realTarget) {\n const inButton =\n realTarget.tagName === 'BUTTON' ||\n (typeof realTarget.closest === 'function' && realTarget.closest('button'));\n if (inButton) return;\n }\n this.#dragStartTime = Date.now();\n try {\n this.setPointerCapture(event.pointerId);\n } catch {\n /* not capturable; ignore */\n }\n this.setAttribute('data-swiping', 'true');\n this.#pointerStart = { x: event.clientX, y: event.clientY };\n if (!this.#swipeDirections) {\n // Read effective position from data-y-position/data-x-position which the toaster\n // sets on every toast (whether or not the toast has its own `position` attribute).\n const y = this.getAttribute('data-y-position');\n const x = this.getAttribute('data-x-position');\n const dirs: SwipeDirection[] = [];\n if (y === 'top' || y === 'bottom') dirs.push(y);\n if (x === 'left' || x === 'right') dirs.push(x);\n this.#swipeDirections = dirs.length > 0 ? dirs : ['bottom', 'right'];\n }\n };\n\n #onPointerMove = (event: PointerEvent) => {\n if (!this.#pointerStart || !this.#isDismissible()) return;\n if ((window.getSelection()?.toString().length ?? 0) > 0) return;\n\n const yDelta = event.clientY - this.#pointerStart.y;\n const xDelta = event.clientX - this.#pointerStart.x;\n const dirs = this.#swipeDirections!;\n\n if (!this.#swipeDirection && (Math.abs(xDelta) > 1 || Math.abs(yDelta) > 1)) {\n this.#swipeDirection = Math.abs(xDelta) > Math.abs(yDelta) ? 'x' : 'y';\n }\n\n const dampen = (delta: number) => 1 / (1.5 + Math.abs(delta) / 20);\n\n let sx = 0;\n let sy = 0;\n if (this.#swipeDirection === 'y') {\n if (dirs.includes('top') || dirs.includes('bottom')) {\n if ((dirs.includes('top') && yDelta < 0) || (dirs.includes('bottom') && yDelta > 0)) {\n sy = yDelta;\n } else {\n const d = yDelta * dampen(yDelta);\n sy = Math.abs(d) < Math.abs(yDelta) ? d : yDelta;\n }\n }\n } else if (this.#swipeDirection === 'x') {\n if (dirs.includes('left') || dirs.includes('right')) {\n if ((dirs.includes('left') && xDelta < 0) || (dirs.includes('right') && xDelta > 0)) {\n sx = xDelta;\n } else {\n const d = xDelta * dampen(xDelta);\n sx = Math.abs(d) < Math.abs(xDelta) ? d : xDelta;\n }\n }\n }\n\n if (Math.abs(sx) > 0 || Math.abs(sy) > 0) this.setAttribute('data-swiped', 'true');\n this.style.setProperty('--swipe-amount-x', `${sx}px`);\n this.style.setProperty('--swipe-amount-y', `${sy}px`);\n };\n\n #onPointerUp = () => {\n if (this.getAttribute('data-swipe-out') === 'true' || !this.#isDismissible()) {\n this.#pointerStart = null;\n this.#swipeDirection = null;\n this.setAttribute('data-swiping', 'false');\n return;\n }\n const sx = parseFloat(this.style.getPropertyValue('--swipe-amount-x')) || 0;\n const sy = parseFloat(this.style.getPropertyValue('--swipe-amount-y')) || 0;\n const time = Math.max(1, Date.now() - this.#dragStartTime);\n const amount = this.#swipeDirection === 'x' ? sx : sy;\n const velocity = Math.abs(amount) / time;\n\n if (Math.abs(amount) >= SWIPE_THRESHOLD || velocity > SWIPE_VELOCITY_THRESHOLD) {\n if (this.#swipeDirection === 'x') {\n this.setAttribute('data-swipe-direction', sx > 0 ? 'right' : 'left');\n } else {\n this.setAttribute('data-swipe-direction', sy > 0 ? 'down' : 'up');\n }\n this.setAttribute('data-swipe-out', 'true');\n this.dismiss();\n } else {\n this.style.setProperty('--swipe-amount-x', '0px');\n this.style.setProperty('--swipe-amount-y', '0px');\n this.setAttribute('data-swiped', 'false');\n }\n this.setAttribute('data-swiping', 'false');\n this.#pointerStart = null;\n this.#swipeDirection = null;\n };\n}\n\nif (typeof customElements !== 'undefined' && !customElements.get('sonner-toast')) {\n customElements.define('sonner-toast', SonnerToast);\n}\n",
10
+ "import { DEFAULT_HOTKEY, GAP, TOAST_WIDTH, VISIBLE_TOASTS_AMOUNT } from './constants.js';\nimport { registerToaster, unregisterToaster } from './registry.js';\nimport { getToasterSheet } from './styles.js';\nimport { SonnerToast } from './sonner-toast.js';\nimport type {\n Position,\n SonnerToastElement,\n SonnerToasterElement,\n Theme,\n ToasterOptions,\n} from './types.js';\n\nconst HTMLElementCtor: typeof HTMLElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as unknown as typeof HTMLElement);\n\nfunction parseOffsetValue(v: string | number | undefined, fallback: string): string {\n if (v == null) return fallback;\n if (typeof v === 'number') return `${v}px`;\n return v;\n}\n\nfunction applyOffsetVars(\n host: HTMLElement,\n opts: ToasterOptions['offset'],\n prefix: string,\n fallback: string,\n) {\n const sides = ['top', 'right', 'bottom', 'left'] as const;\n if (opts == null || typeof opts === 'string' || typeof opts === 'number') {\n const v = parseOffsetValue(opts, fallback);\n for (const side of sides) host.style.setProperty(`${prefix}-${side}`, v);\n } else {\n for (const side of sides) {\n host.style.setProperty(`${prefix}-${side}`, parseOffsetValue(opts[side], fallback));\n }\n }\n}\n\nexport class SonnerToaster extends HTMLElementCtor implements SonnerToasterElement {\n static get observedAttributes() {\n return [\n 'position',\n 'theme',\n 'rich-colors',\n 'expand',\n 'duration',\n 'gap',\n 'visible-toasts',\n 'close-button',\n 'invert',\n 'dir',\n 'offset',\n 'mobile-offset',\n 'hotkey',\n 'container-aria-label',\n ];\n }\n\n #shadow: ShadowRoot;\n #alertAnnouncer!: HTMLDivElement;\n #childObserver: MutationObserver;\n #resizeObserver: ResizeObserver;\n #toasts: SonnerToast[] = [];\n /** Last measured height per toast. We keep the prior value while a toast is mid-removal\n * (data-removed='true') so its shrinking does not corrupt the offsets of survivors. */\n #heights = new Map<SonnerToast, number>();\n /** True during the synchronous measurement window inside #reflow so the ResizeObserver\n * doesn't recursively re-fire while we're toggling style.height to measure naturals. */\n #measuring = false;\n #expanded = false;\n #interacting = false;\n #themeMql: MediaQueryList | null = null;\n #themeMqlHandler: ((e: MediaQueryListEvent | MediaQueryList) => void) | null = null;\n\n constructor() {\n super();\n this.#shadow = this.attachShadow({ mode: 'open' });\n this.#shadow.adoptedStyleSheets = [getToasterSheet()];\n // Dedicated alert region for urgent re-announcements (e.g. promise\n // loading → error). Browser/SR support for changing a toast's own\n // aria-live mid-flight is inconsistent; routing the new text through\n // a fresh, stable live region guarantees the alert is announced.\n this.#shadow.innerHTML =\n '<div data-frame part=\"frame\"><slot></slot></div>' +\n '<div data-alert-announcer role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" ' +\n 'style=\"position:absolute;left:0;top:0;width:1px;height:1px;margin:-1px;padding:0;' +\n 'overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;' +\n 'pointer-events:none\"></div>';\n this.#alertAnnouncer = this.#shadow.querySelector('[data-alert-announcer]') as HTMLDivElement;\n\n this.#childObserver = new MutationObserver((records) => {\n let changed = false;\n for (const r of records) {\n for (const node of Array.from(r.addedNodes)) {\n if (node instanceof SonnerToast) {\n this.#toasts.unshift(node);\n this.#resizeObserver.observe(node);\n this.#decorateToast(node);\n changed = true;\n }\n }\n for (const node of Array.from(r.removedNodes)) {\n if (node instanceof SonnerToast) {\n this.#toasts = this.#toasts.filter((t) => t !== node);\n this.#heights.delete(node);\n this.#resizeObserver.unobserve(node);\n changed = true;\n }\n }\n }\n if (changed) this.#reflow({ remeasure: true });\n });\n\n // ResizeObserver fires every frame while a height transition is running (because the\n // rendered size IS changing). We must NOT re-measure on those events — doing so would\n // temporarily set style.height='auto' on a mid-transition toast and cancel the\n // animation. RO here only re-applies layout from the cached heights.\n this.#resizeObserver = new ResizeObserver(() => this.#reflow({ remeasure: false }));\n\n this.addEventListener('mouseenter', this.#onPointerEnter);\n this.addEventListener('mouseleave', this.#onPointerLeave);\n this.addEventListener('focusin', this.#onFocusIn);\n this.addEventListener('focusout', this.#onFocusOut);\n this.addEventListener('sonner-toast-dismissed', () => this.#reflow({ remeasure: false }));\n // Content actually changed — re-measure the toast that updated.\n this.addEventListener('sonner-toast-updated', () => this.#reflow({ remeasure: true }));\n this.addEventListener('sonner-toast-mounted', () => this.#reflow({ remeasure: true }));\n }\n\n connectedCallback() {\n if (!this.hasAttribute('tabindex')) this.tabIndex = -1;\n if (!this.hasAttribute('role')) this.setAttribute('role', 'region');\n if (!this.hasAttribute('aria-label'))\n this.setAttribute('aria-label', this.getAttribute('container-aria-label') ?? 'Notifications');\n this.setAttribute('data-sonner-toaster', '');\n this.#applyPosition();\n this.#applyTheme();\n this.#applyDir();\n this.#applyGap();\n this.#applyWidth();\n this.#applyOffsets();\n\n this.#childObserver.observe(this, { childList: true });\n for (const child of Array.from(this.children)) {\n if (child instanceof SonnerToast) {\n this.#toasts.unshift(child);\n this.#resizeObserver.observe(child);\n this.#decorateToast(child);\n }\n }\n document.addEventListener('keydown', this.#onKeyDown);\n window.addEventListener('resize', this.#onWindowResize);\n registerToaster(this);\n this.#reflow({ remeasure: true });\n }\n\n disconnectedCallback() {\n this.#childObserver.disconnect();\n this.#resizeObserver.disconnect();\n document.removeEventListener('keydown', this.#onKeyDown);\n window.removeEventListener('resize', this.#onWindowResize);\n if (this.#themeMql && this.#themeMqlHandler) {\n this.#themeMql.removeEventListener('change', this.#themeMqlHandler);\n }\n unregisterToaster(this);\n }\n\n attributeChangedCallback(name: string, _old: string | null, _val: string | null) {\n if (!this.isConnected) return;\n switch (name) {\n case 'position':\n this.#applyPosition();\n this.#applyToastPositions();\n this.#reflow();\n break;\n case 'theme':\n this.#applyTheme();\n break;\n case 'dir':\n this.#applyDir();\n break;\n case 'gap':\n this.#applyGap();\n this.#reflow();\n break;\n case 'visible-toasts':\n this.#reflow();\n break;\n case 'expand':\n this.#expanded = this.hasAttribute('expand');\n for (const t of this.#toasts) t.setPaused(this.#expanded || this.#interacting);\n this.#reflow();\n break;\n case 'close-button':\n case 'rich-colors':\n case 'invert':\n this.#propagateBoolean(name);\n break;\n case 'offset':\n case 'mobile-offset':\n this.#applyOffsets();\n break;\n case 'container-aria-label':\n this.setAttribute('aria-label', this.getAttribute('container-aria-label') ?? 'Notifications');\n break;\n }\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n addToast(el: SonnerToastElement): SonnerToastElement {\n this.appendChild(el);\n return el;\n }\n\n /** Re-announce `text` through the dedicated assertive live region. Used when\n * a toast transitions to an urgent type (error/warning) after mount — the\n * toast's own aria-live change is unreliable across screen readers, so we\n * route the alert through a fresh region whose announcement behavior is\n * consistent. The clear-then-set pattern forces SRs that diff content to\n * treat the new text as a new announcement. */\n announceUrgent(text: string): void {\n this.#alertAnnouncer.textContent = '';\n requestAnimationFrame(() => {\n this.#alertAnnouncer.textContent = text;\n });\n }\n\n dismissAll(): void {\n // Iterate live children so toasts appended this tick (before the MutationObserver\n // fires) are still covered.\n for (const child of Array.from(this.children)) {\n if (child instanceof SonnerToast) child.dismiss();\n }\n }\n\n // ─── Configuration application ───────────────────────────────────────────\n\n #getPosition(): Position {\n return (this.getAttribute('position') as Position) || 'bottom-right';\n }\n\n #applyPosition() {\n const [y, x] = this.#getPosition().split('-');\n if (y) this.setAttribute('data-y-position', y);\n if (x) this.setAttribute('data-x-position', x);\n }\n\n #applyTheme() {\n if (this.#themeMql && this.#themeMqlHandler) {\n this.#themeMql.removeEventListener('change', this.#themeMqlHandler);\n this.#themeMql = null;\n this.#themeMqlHandler = null;\n }\n const theme = (this.getAttribute('theme') as Theme) || 'light';\n if (theme === 'system') {\n this.#themeMql = window.matchMedia('(prefers-color-scheme: dark)');\n const apply = (mql: MediaQueryList | MediaQueryListEvent) => {\n this.setAttribute('data-sonner-theme', mql.matches ? 'dark' : 'light');\n };\n this.#themeMqlHandler = apply;\n this.#themeMql.addEventListener('change', apply);\n apply(this.#themeMql);\n } else {\n this.setAttribute('data-sonner-theme', theme);\n }\n }\n\n #applyDir() {\n const dir = this.getAttribute('dir');\n if (dir === 'auto' || !dir) {\n const computed = window.getComputedStyle(document.documentElement).direction || 'ltr';\n this.setAttribute('dir', computed);\n }\n }\n\n #applyGap() {\n const raw = this.getAttribute('gap');\n const gap = raw ? Number(raw) : GAP;\n this.style.setProperty('--gap', `${Number.isFinite(gap) ? gap : GAP}px`);\n }\n\n #applyWidth() {\n this.style.setProperty('--width', `${TOAST_WIDTH}px`);\n }\n\n #applyOffsets() {\n const off = this.getAttribute('offset');\n const mobileOff = this.getAttribute('mobile-offset');\n applyOffsetVars(this, off ?? undefined, '--offset', '24px');\n applyOffsetVars(this, mobileOff ?? undefined, '--mobile-offset', '16px');\n }\n\n #applyToastPositions() {\n for (const t of this.#toasts) {\n if (!t.hasAttribute('position')) {\n const [y, x] = this.#getPosition().split('-');\n if (y) t.setAttribute('data-y-position', y);\n if (x) t.setAttribute('data-x-position', x);\n }\n }\n }\n\n /** Mirror a toaster-level boolean attribute (close-button, rich-colors, invert) onto\n * every existing toast that hasn't set the same attribute itself. Per-toast overrides\n * still win. */\n #propagateBoolean(attr: 'close-button' | 'rich-colors' | 'invert') {\n const on = this.hasAttribute(attr);\n for (const t of this.#toasts) {\n // Skip if the toast explicitly opted out with `attr=\"false\"` — that's a per-toast override.\n if (t.getAttribute(attr) === 'false') continue;\n if (on) t.setAttribute(attr, '');\n else t.removeAttribute(attr);\n }\n }\n\n #decorateToast(toast: SonnerToast) {\n if (!toast.hasAttribute('position')) {\n const [y, x] = this.#getPosition().split('-');\n if (y) toast.setAttribute('data-y-position', y);\n if (x) toast.setAttribute('data-x-position', x);\n }\n if (!toast.hasAttribute('duration')) {\n const inherit = this.getAttribute('duration');\n if (inherit) toast.setAttribute('duration', inherit);\n }\n if (!toast.hasAttribute('close-button') && this.hasAttribute('close-button')) {\n toast.setAttribute('close-button', '');\n }\n if (!toast.hasAttribute('rich-colors') && this.hasAttribute('rich-colors')) {\n toast.setAttribute('rich-colors', '');\n }\n if (!toast.hasAttribute('invert') && this.hasAttribute('invert')) {\n toast.setAttribute('invert', '');\n }\n }\n\n // ─── Stacking math ───────────────────────────────────────────────────────\n\n #reflow(opts: { remeasure: boolean } = { remeasure: false }) {\n const visibleAmount = Number(this.getAttribute('visible-toasts') ?? VISIBLE_TOASTS_AMOUNT);\n\n // Only measure when explicitly requested (toast added / updated / mounted / window\n // resized). Measuring on every reflow corrupts running height transitions, because\n // the temp `style.height='auto'` cancels them.\n if (opts.remeasure) {\n this.#measuring = true;\n for (const t of this.#toasts) {\n if (t.getAttribute('data-removed') === 'true') continue;\n const prior = t.style.height;\n t.style.height = 'auto';\n this.#heights.set(t, t.getBoundingClientRect().height);\n t.style.height = prior;\n }\n this.#measuring = false;\n }\n\n const active = this.#toasts.filter((t) => t.getAttribute('data-removed') !== 'true');\n const frontHeight = active.length > 0 ? (this.#heights.get(active[0]!) ?? 0) : 0;\n const gap = this.#gapPx();\n const expanded = this.#expanded || this.#interacting;\n let cumulative = 0;\n\n // Single inherited value for all toasts — when this changes, every toast's\n // height: var(--front-toast-height) re-resolves and transitions in lockstep.\n this.style.setProperty('--front-toast-height', `${frontHeight}px`);\n\n for (let i = 0; i < active.length; i++) {\n const toast = active[i]!;\n const h = this.#heights.get(toast) ?? 0;\n const isFront = i === 0;\n const offset = i === 0 ? 0 : cumulative + i * gap;\n cumulative += h;\n\n toast.style.setProperty('--index', String(i));\n toast.style.setProperty('--toasts-before', String(i));\n toast.style.setProperty('--z-index', String(active.length - i));\n toast.style.setProperty('--offset', `${offset}px`);\n toast.style.setProperty('--initial-height', `${h}px`);\n // height itself is driven by CSS now (interpolate-size handles auto↔pixel).\n toast.setAttribute('data-index', String(i));\n toast.setAttribute('data-front', String(isFront));\n toast.setAttribute('data-visible', String(i + 1 <= visibleAmount));\n toast.setAttribute('data-expanded', String(expanded));\n // Hide non-front toasts from assistive tech when collapsed: they're\n // visually stacked behind and shouldn't compete with the front toast\n // for screen-reader attention. Expanding the stack reveals them again.\n if (expanded || isFront) toast.removeAttribute('aria-hidden');\n else toast.setAttribute('aria-hidden', 'true');\n }\n }\n\n #gapPx(): number {\n const raw = this.getAttribute('gap');\n const n = raw ? Number(raw) : GAP;\n return Number.isFinite(n) ? n : GAP;\n }\n\n // ─── Hover / expand / hotkey ─────────────────────────────────────────────\n\n #onPointerEnter = () => {\n this.#interacting = true;\n for (const t of this.#toasts) t.setPaused(true);\n this.#reflow();\n };\n\n #onPointerLeave = () => {\n this.#interacting = false;\n for (const t of this.#toasts) t.setPaused(false);\n this.#reflow();\n };\n\n #onFocusIn = () => {\n this.#interacting = true;\n for (const t of this.#toasts) t.setPaused(true);\n this.#reflow();\n };\n\n #onFocusOut = (e: FocusEvent) => {\n const next = e.relatedTarget as Node | null;\n if (next && this.contains(next)) return;\n this.#interacting = false;\n for (const t of this.#toasts) t.setPaused(false);\n this.#reflow();\n };\n\n #onWindowResize = () => this.#reflow({ remeasure: true });\n\n #onKeyDown = (event: KeyboardEvent) => {\n // Don't hijack the hotkey when the user is typing.\n const target = event.target as HTMLElement | null;\n if (target) {\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable) {\n return;\n }\n }\n const hotkey = this.#hotkey();\n const matches = hotkey.every((key) => {\n if (key === 'altKey' || key === 'ctrlKey' || key === 'shiftKey' || key === 'metaKey') {\n return event[key as 'altKey'];\n }\n return event.code === key;\n });\n if (matches) {\n this.#expanded = true;\n for (const t of this.#toasts) t.setPaused(true);\n this.focus();\n this.#reflow();\n return;\n }\n if (event.key === 'Escape' && this.#expanded && this.contains(document.activeElement)) {\n this.#expanded = false;\n for (const t of this.#toasts) t.setPaused(false);\n this.#reflow();\n }\n };\n\n #hotkey(): readonly string[] {\n const raw = this.getAttribute('hotkey');\n if (!raw) return DEFAULT_HOTKEY;\n return raw.split('+').map((s) => s.trim());\n }\n}\n\nif (typeof customElements !== 'undefined' && !customElements.get('sonner-toaster')) {\n customElements.define('sonner-toaster', SonnerToaster);\n}\n",
11
+ "import { defaultToaster, dismissAllToasts, getToast, nextToastId } from './registry.js';\nimport { SonnerToast } from './sonner-toast.js';\nimport { SonnerToaster } from './sonner-toaster.js';\nimport type {\n PromiseOptions,\n SonnerToastElement,\n ToastContent,\n ToastOptions,\n ToastType,\n} from './types.js';\n\ninterface CreateOptions extends ToastOptions {\n title?: ToastContent;\n type?: ToastType;\n}\n\nfunction ensureToaster(toasterId?: string): SonnerToaster {\n if (toasterId) {\n const byId = document.getElementById(toasterId);\n if (byId instanceof SonnerToaster) return byId;\n }\n let host = defaultToaster() as SonnerToaster | undefined;\n if (!host) {\n host = document.createElement('sonner-toaster') as SonnerToaster;\n document.body.appendChild(host);\n }\n return host;\n}\n\nfunction buildOrUpdate(options: CreateOptions): SonnerToastElement {\n const id = options.id ?? nextToastId();\n const existing = getToast(id);\n if (existing) {\n existing.update(options);\n return existing;\n }\n const el = document.createElement('sonner-toast') as SonnerToast;\n el.toastId = id;\n el.update(options);\n el.setHandlers({ onDismiss: options.onDismiss, onAutoClose: options.onAutoClose });\n ensureToaster(options.toasterId).addToast(el);\n return el;\n}\n\nfunction variant(type: ToastType) {\n return (message: ToastContent, opts?: ToastOptions): SonnerToastElement =>\n buildOrUpdate({ ...opts, type, title: message });\n}\n\nfunction basic(message: ToastContent, opts?: ToastOptions): SonnerToastElement {\n return buildOrUpdate({ ...opts, type: 'default', title: message });\n}\n\nfunction dismiss(id?: string | number): void {\n if (id !== undefined) {\n getToast(id)?.dismiss();\n return;\n }\n dismissAllToasts();\n}\n\nfunction custom(\n builder: (id: string | number) => HTMLElement,\n opts?: ToastOptions,\n): SonnerToastElement {\n const id = opts?.id ?? nextToastId();\n const el = document.createElement('sonner-toast') as SonnerToast;\n el.toastId = id;\n el.setAttribute('data-styled', 'false');\n if (opts?.duration !== undefined) el.setAttribute('duration', String(opts.duration));\n if (opts?.dismissible === false) el.setAttribute('dismissible', 'false');\n if (opts?.position) el.setAttribute('position', opts.position);\n if (opts?.testId !== undefined) el.setAttribute('data-testid', opts.testId);\n const content = builder(id);\n el.appendChild(content);\n el.setHandlers({ onDismiss: opts?.onDismiss, onAutoClose: opts?.onAutoClose });\n ensureToaster(opts?.toasterId).addToast(el);\n return el;\n}\n\nasync function resolveContent<T>(\n value: ToastContent | ((arg: T) => ToastContent) | undefined,\n arg: T,\n): Promise<ToastContent | undefined> {\n if (value === undefined) return undefined;\n if (typeof value === 'function') {\n // ToastContent allows zero-arg functions too; distinguish by length.\n return (value as (a: T) => ToastContent).length === 0\n ? (value as () => ToastContent)()\n : (value as (a: T) => ToastContent)(arg);\n }\n return value;\n}\n\nfunction promise<T>(\n promiseOrFn: Promise<T> | (() => Promise<T>),\n options: PromiseOptions<T>,\n): SonnerToastElement & { unwrap: () => Promise<T> } {\n const id = options.id ?? nextToastId();\n // Carry forward everything except the promise-specific resolver fields when building the toast.\n const { loading: _l, success: _s, error: _e, description: _d, finally: _f, ...rest } = options;\n const loadingEl = buildOrUpdate({\n ...rest,\n id,\n type: 'loading',\n title: options.loading,\n duration: Infinity,\n dismissible: options.dismissible ?? false,\n });\n\n const work = Promise.resolve(typeof promiseOrFn === 'function' ? promiseOrFn() : promiseOrFn);\n\n let result: ['resolve', T] | ['reject', unknown] | null = null;\n\n const settled = work\n .then(async (value) => {\n result = ['resolve', value];\n const title = await resolveContent(options.success, value);\n const desc = await resolveContent(options.description, value);\n if (title !== undefined) {\n loadingEl.update({\n ...rest,\n id,\n type: 'success',\n title,\n description: desc,\n duration: options.duration,\n dismissible: options.dismissible ?? true,\n });\n } else {\n loadingEl.dismiss();\n }\n })\n .catch(async (err) => {\n result = ['reject', err];\n const title = await resolveContent(options.error, err);\n const desc = await resolveContent(options.description, err);\n if (title !== undefined) {\n loadingEl.update({\n ...rest,\n id,\n type: 'error',\n title,\n description: desc,\n duration: options.duration,\n dismissible: options.dismissible ?? true,\n });\n } else {\n loadingEl.dismiss();\n }\n })\n .finally(() => options.finally?.());\n\n const unwrap = () =>\n new Promise<T>((resolve, reject) => {\n settled.then(() => {\n if (!result) return reject(new Error('promise toast settled without a result'));\n if (result[0] === 'resolve') resolve(result[1]);\n else reject(result[1]);\n });\n });\n\n return Object.assign(loadingEl, { unwrap });\n}\n\nexport const toast = Object.assign(basic, {\n success: variant('success'),\n error: variant('error'),\n info: variant('info'),\n warning: variant('warning'),\n loading: (message: ToastContent, opts?: ToastOptions) =>\n buildOrUpdate({\n ...opts,\n type: 'loading',\n title: message,\n duration: opts?.duration ?? Infinity,\n }),\n message: basic,\n promise,\n custom,\n dismiss,\n getToast,\n});\n",
12
+ "// Public API: re-exported declaratively so the entry point's exports\n// survive tree-shaking. The window.toast side-effect uses a separately\n// renamed import (`_toast`) — sharing a name with a re-export trips\n// newer Bun bundlers into emitting broken `toast2 as toast` aliases.\nexport { SonnerToast } from './sonner-toast.js';\nexport { SonnerToaster } from './sonner-toaster.js';\nexport { toast } from './toast.js';\n\nimport type { SonnerToast as _SonnerToast } from './sonner-toast.js';\nimport type { SonnerToaster as _SonnerToaster } from './sonner-toaster.js';\nimport { toast as _toast } from './toast.js';\nexport type {\n Position,\n PromiseOptions,\n SonnerToastElement,\n SonnerToasterElement,\n SwipeDirection,\n Theme,\n ToastAction,\n ToastContent,\n ToastOptions,\n ToastType,\n ToasterOptions,\n} from './types.js';\n\nif (typeof window !== 'undefined')\n (window as Window & { toast?: typeof _toast }).toast = _toast;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sonner-toast': _SonnerToast;\n 'sonner-toaster': _SonnerToaster;\n }\n}\n"
13
+ ],
14
+ "mappings": "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",
15
+ "debugId": "038A38E1BC01A40B64756E2164756E21",
16
+ "names": []
17
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Stylesheets shared across both custom elements via adoptedStyleSheets.
3
+ *
4
+ * CSS lives in plain `.css` files under `./styles/` so editors give full
5
+ * language support (highlighting, autocomplete, Prettier). Bun's bundler
6
+ * inlines the file contents as strings via the `with { type: 'text' }`
7
+ * import attribute; we then wrap each in a CSSStyleSheet at runtime.
8
+ *
9
+ * Two scopes:
10
+ * - toaster.css: positioning, theme palettes, dir-based vars (cascades into
11
+ * child shadow trees via inherited custom properties).
12
+ * - toast.css: per-toast layout, animations, swipe, rich colors (reads
13
+ * the inherited theme vars set by the toaster).
14
+ */
15
+ export declare function getToasterSheet(): CSSStyleSheet;
16
+ export declare function getToastSheet(): CSSStyleSheet;
@@ -0,0 +1,21 @@
1
+ import { getToast } from './registry.js';
2
+ import type { PromiseOptions, SonnerToastElement, ToastContent, ToastOptions } from './types.js';
3
+ declare function basic(message: ToastContent, opts?: ToastOptions): SonnerToastElement;
4
+ declare function dismiss(id?: string | number): void;
5
+ declare function custom(builder: (id: string | number) => HTMLElement, opts?: ToastOptions): SonnerToastElement;
6
+ declare function promise<T>(promiseOrFn: Promise<T> | (() => Promise<T>), options: PromiseOptions<T>): SonnerToastElement & {
7
+ unwrap: () => Promise<T>;
8
+ };
9
+ export declare const toast: typeof basic & {
10
+ success: (message: ToastContent, opts?: ToastOptions) => SonnerToastElement;
11
+ error: (message: ToastContent, opts?: ToastOptions) => SonnerToastElement;
12
+ info: (message: ToastContent, opts?: ToastOptions) => SonnerToastElement;
13
+ warning: (message: ToastContent, opts?: ToastOptions) => SonnerToastElement;
14
+ loading: (message: ToastContent, opts?: ToastOptions) => SonnerToastElement;
15
+ message: typeof basic;
16
+ promise: typeof promise;
17
+ custom: typeof custom;
18
+ dismiss: typeof dismiss;
19
+ getToast: typeof getToast;
20
+ };
21
+ export {};
@@ -0,0 +1,85 @@
1
+ export type ToastType = 'normal' | 'default' | 'success' | 'info' | 'warning' | 'error' | 'loading';
2
+ export type Theme = 'light' | 'dark' | 'system';
3
+ export type Position = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
4
+ export type SwipeDirection = 'top' | 'right' | 'bottom' | 'left';
5
+ /** Content that can be passed as a title, description, or button label.
6
+ * Strings render as text; HTMLElement gets appended; functions are called and their return value used. */
7
+ export type ToastContent = string | Node | (() => string | Node);
8
+ export interface ToastAction {
9
+ label: string;
10
+ onClick?: (event: MouseEvent) => void;
11
+ }
12
+ export interface ToastOptions {
13
+ id?: string | number;
14
+ /** Route this toast to a specific `<sonner-toaster>` by its DOM `id`.
15
+ * Falls back to the default toaster if no element with that id is a toaster. */
16
+ toasterId?: string;
17
+ /** Set as `data-testid` on the toast host element. Survives promise transitions. */
18
+ testId?: string;
19
+ /** Accessible name for this toast's close button. Defaults to `Close: <title>`
20
+ * (or `Close toast` when there is no title). */
21
+ closeButtonAriaLabel?: string;
22
+ description?: ToastContent;
23
+ duration?: number;
24
+ dismissible?: boolean;
25
+ position?: Position;
26
+ closeButton?: boolean;
27
+ richColors?: boolean;
28
+ invert?: boolean;
29
+ icon?: Node | string;
30
+ className?: string;
31
+ action?: ToastAction | HTMLElement;
32
+ cancel?: ToastAction | HTMLElement;
33
+ onDismiss?: (toastEl: SonnerToastElement) => void;
34
+ onAutoClose?: (toastEl: SonnerToastElement) => void;
35
+ }
36
+ export interface PromiseOptions<T> extends Omit<ToastOptions, 'description'> {
37
+ loading: ToastContent;
38
+ success?: ToastContent | ((data: T) => ToastContent);
39
+ error?: ToastContent | ((err: unknown) => ToastContent);
40
+ description?: ToastContent | ((dataOrError: T | unknown) => ToastContent);
41
+ finally?: () => void | Promise<void>;
42
+ }
43
+ export interface ToasterOptions {
44
+ position?: Position;
45
+ theme?: Theme;
46
+ richColors?: boolean;
47
+ expand?: boolean;
48
+ duration?: number;
49
+ gap?: number;
50
+ visibleToasts?: number;
51
+ closeButton?: boolean;
52
+ invert?: boolean;
53
+ dir?: 'ltr' | 'rtl' | 'auto';
54
+ hotkey?: readonly string[];
55
+ offset?: string | number | {
56
+ top?: string | number;
57
+ right?: string | number;
58
+ bottom?: string | number;
59
+ left?: string | number;
60
+ };
61
+ mobileOffset?: string | number | {
62
+ top?: string | number;
63
+ right?: string | number;
64
+ bottom?: string | number;
65
+ left?: string | number;
66
+ };
67
+ swipeDirections?: SwipeDirection[];
68
+ containerAriaLabel?: string;
69
+ }
70
+ export interface SonnerToastElement extends HTMLElement {
71
+ toastId: string | number;
72
+ toastType: ToastType;
73
+ dismiss(): void;
74
+ update(options: ToastOptions & {
75
+ title?: ToastContent;
76
+ type?: ToastType;
77
+ }): void;
78
+ }
79
+ export interface SonnerToasterElement extends HTMLElement {
80
+ /** Append a freshly-built sonner-toast element. Returns the element for chaining/updating. */
81
+ addToast(el: SonnerToastElement): SonnerToastElement;
82
+ dismissAll(): void;
83
+ /** Re-announce `text` via the toaster's dedicated assertive live region. */
84
+ announceUrgent(text: string): void;
85
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "sonner-wc",
3
+ "version": "0.1.0",
4
+ "description": "Sonner's toast UX as a framework-agnostic Web Component. Drop in anywhere.",
5
+ "type": "module",
6
+ "main": "./dist/sonner-wc.js",
7
+ "module": "./dist/sonner-wc.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/sonner-wc.js"
13
+ },
14
+ "./bundle": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/sonner-wc.bundle.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "engines": {
25
+ "bun": ">=1.1"
26
+ },
27
+ "workspaces": [
28
+ "site"
29
+ ],
30
+ "sideEffects": [
31
+ "./dist/sonner-wc.js",
32
+ "./dist/sonner-wc.bundle.js"
33
+ ],
34
+ "scripts": {
35
+ "build:wc": "bun run build.ts",
36
+ "build:site": "cd site && bun run build",
37
+ "build": "bun run build:wc && bun run build:site",
38
+ "dev:wc": "bun run scripts/dev.ts",
39
+ "dev:site": "cd site && bun run dev",
40
+ "dev": "concurrently -n wc,site -c blue,magenta \"bun run dev:wc\" \"bun run dev:site\"",
41
+ "test": "bun test test/toast.test.ts",
42
+ "test:e2e": "playwright test",
43
+ "test:e2e:ui": "playwright test --ui",
44
+ "typecheck": "bunx tsc --noEmit",
45
+ "format": "prettier --write \"**/*.{ts,js,css,html,md,json}\"",
46
+ "format:check": "prettier --check \"**/*.{ts,js,css,html,md,json}\"",
47
+ "lint:pkg": "publint",
48
+ "lint:types": "attw --pack . --ignore-rules cjs-resolves-to-esm no-resolution",
49
+ "lint:exports": "bun run build:wc && bun run lint:pkg && bun run lint:types"
50
+ },
51
+ "keywords": [
52
+ "toast",
53
+ "notification",
54
+ "sonner",
55
+ "web-component",
56
+ "custom-element"
57
+ ],
58
+ "license": "MIT",
59
+ "devDependencies": {
60
+ "@arethetypeswrong/cli": "^0.18.2",
61
+ "@happy-dom/global-registrator": "^20.9.0",
62
+ "@playwright/test": "^1.60.0",
63
+ "@types/bun": "latest",
64
+ "concurrently": "^9.2.1",
65
+ "prettier": "^3.8.3",
66
+ "publint": "^0.3.21",
67
+ "typescript": "^5.6.0"
68
+ }
69
+ }