@vielzeug/refine 2.3.0 → 3.0.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.
Files changed (314) hide show
  1. package/README.md +5 -18
  2. package/dist/accordion-item.cjs +1 -1
  3. package/dist/accordion-item.cjs.map +1 -1
  4. package/dist/accordion-item.js +1 -1
  5. package/dist/accordion-item.js.map +1 -1
  6. package/dist/accordion.cjs.map +1 -1
  7. package/dist/accordion.js.map +1 -1
  8. package/dist/async.cjs +1 -1
  9. package/dist/async.cjs.map +1 -1
  10. package/dist/async.js +3 -3
  11. package/dist/async.js.map +1 -1
  12. package/dist/box.cjs.map +1 -1
  13. package/dist/box.js.map +1 -1
  14. package/dist/card.cjs +1 -1
  15. package/dist/card.cjs.map +1 -1
  16. package/dist/card.js +3 -3
  17. package/dist/card.js.map +1 -1
  18. package/dist/chat-message.cjs +1 -1
  19. package/dist/chat-message.cjs.map +1 -1
  20. package/dist/chat-message.js +1 -1
  21. package/dist/chat-message.js.map +1 -1
  22. package/dist/checkbox-group.cjs +1 -1
  23. package/dist/checkbox-group.cjs.map +1 -1
  24. package/dist/checkbox-group.js +1 -1
  25. package/dist/checkbox-group.js.map +1 -1
  26. package/dist/combobox.cjs +10 -8
  27. package/dist/combobox.cjs.map +1 -1
  28. package/dist/combobox.js +62 -51
  29. package/dist/combobox.js.map +1 -1
  30. package/dist/command-palette.cjs +1 -1
  31. package/dist/command-palette.cjs.map +1 -1
  32. package/dist/command-palette.js +6 -2
  33. package/dist/command-palette.js.map +1 -1
  34. package/dist/content/card/card.css.cjs +1 -1
  35. package/dist/content/card/card.css.cjs.map +1 -1
  36. package/dist/content/card/card.css.js +1 -1
  37. package/dist/content/card/card.css.js.map +1 -1
  38. package/dist/content/card/card.d.ts +2 -2
  39. package/dist/content/card/card.d.ts.map +1 -1
  40. package/dist/content/index.d.ts +2 -0
  41. package/dist/content/index.d.ts.map +1 -1
  42. package/dist/content/list/list-item.css.cjs +1 -1
  43. package/dist/content/list/list-item.css.cjs.map +1 -1
  44. package/dist/content/list/list-item.css.js +1 -1
  45. package/dist/content/list/list-item.css.js.map +1 -1
  46. package/dist/content/list/list-item.d.ts +9 -0
  47. package/dist/content/list/list-item.d.ts.map +1 -1
  48. package/dist/content/pagination/pagination.css.cjs +1 -1
  49. package/dist/content/pagination/pagination.css.cjs.map +1 -1
  50. package/dist/content/pagination/pagination.css.js +1 -1
  51. package/dist/content/pagination/pagination.css.js.map +1 -1
  52. package/dist/content/stats/stats.css.cjs +2 -0
  53. package/dist/content/stats/stats.css.cjs.map +1 -0
  54. package/dist/content/stats/stats.css.js +6 -0
  55. package/dist/content/stats/stats.css.js.map +1 -0
  56. package/dist/content/stats/stats.d.ts +72 -0
  57. package/dist/content/stats/stats.d.ts.map +1 -0
  58. package/dist/core/auto-resize.cjs +1 -1
  59. package/dist/core/auto-resize.cjs.map +1 -1
  60. package/dist/core/auto-resize.js +1 -1
  61. package/dist/core/auto-resize.js.map +1 -1
  62. package/dist/core/field-base.cjs +1 -1
  63. package/dist/core/field-base.cjs.map +1 -1
  64. package/dist/core/field-base.d.ts +1 -1
  65. package/dist/core/field-base.js +1 -1
  66. package/dist/core/field-base.js.map +1 -1
  67. package/dist/core/nav.cjs +1 -1
  68. package/dist/core/nav.cjs.map +1 -1
  69. package/dist/core/nav.d.ts +4 -1
  70. package/dist/core/nav.d.ts.map +1 -1
  71. package/dist/core/nav.js +41 -28
  72. package/dist/core/nav.js.map +1 -1
  73. package/dist/core/option-list.cjs +1 -1
  74. package/dist/core/option-list.cjs.map +1 -1
  75. package/dist/core/option-list.d.ts.map +1 -1
  76. package/dist/core/option-list.js +30 -28
  77. package/dist/core/option-list.js.map +1 -1
  78. package/dist/core/slider.cjs +1 -1
  79. package/dist/core/slider.cjs.map +1 -1
  80. package/dist/core/slider.js +1 -1
  81. package/dist/core/slider.js.map +1 -1
  82. package/dist/core/spinner.cjs +1 -1
  83. package/dist/core/spinner.cjs.map +1 -1
  84. package/dist/core/spinner.js +1 -1
  85. package/dist/core/spinner.js.map +1 -1
  86. package/dist/custom-elements.json +5471 -4977
  87. package/dist/datagrid.cjs +219 -199
  88. package/dist/datagrid.cjs.map +1 -1
  89. package/dist/datagrid.js +415 -302
  90. package/dist/datagrid.js.map +1 -1
  91. package/dist/disclosure/accordion/accordion.css.cjs +1 -1
  92. package/dist/disclosure/accordion/accordion.css.cjs.map +1 -1
  93. package/dist/disclosure/accordion/accordion.css.js +1 -1
  94. package/dist/disclosure/accordion/accordion.css.js.map +1 -1
  95. package/dist/disclosure/accordion/accordion.d.ts +5 -5
  96. package/dist/disclosure/accordion/accordion.d.ts.map +1 -1
  97. package/dist/disclosure/accordion-item/accordion-item.css.cjs +1 -1
  98. package/dist/disclosure/accordion-item/accordion-item.css.cjs.map +1 -1
  99. package/dist/disclosure/accordion-item/accordion-item.css.js +1 -1
  100. package/dist/disclosure/accordion-item/accordion-item.css.js.map +1 -1
  101. package/dist/disclosure/accordion-item/accordion-item.d.ts +3 -3
  102. package/dist/disclosure/accordion-item/accordion-item.d.ts.map +1 -1
  103. package/dist/disclosure/tab-item/tab-item.css.cjs +1 -1
  104. package/dist/disclosure/tab-item/tab-item.css.cjs.map +1 -1
  105. package/dist/disclosure/tab-item/tab-item.css.js +1 -1
  106. package/dist/disclosure/tab-item/tab-item.css.js.map +1 -1
  107. package/dist/disclosure/tab-item/tab-item.d.ts +6 -3
  108. package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
  109. package/dist/disclosure/tabs/tabs.css.cjs +1 -1
  110. package/dist/disclosure/tabs/tabs.css.cjs.map +1 -1
  111. package/dist/disclosure/tabs/tabs.css.js +1 -1
  112. package/dist/disclosure/tabs/tabs.css.js.map +1 -1
  113. package/dist/disclosure/tabs/tabs.d.ts +9 -5
  114. package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
  115. package/dist/drawer.cjs +1 -1
  116. package/dist/drawer.cjs.map +1 -1
  117. package/dist/drawer.js +1 -1
  118. package/dist/drawer.js.map +1 -1
  119. package/dist/feedback/toast/toast.d.ts.map +1 -1
  120. package/dist/file-input.cjs +1 -1
  121. package/dist/file-input.cjs.map +1 -1
  122. package/dist/file-input.js +2 -2
  123. package/dist/file-input.js.map +1 -1
  124. package/dist/frameworks/elements.d.ts +4 -85
  125. package/dist/frameworks/react.d.ts +5 -4
  126. package/dist/frameworks/vue.d.ts +4 -4
  127. package/dist/grid.cjs +2 -2
  128. package/dist/grid.cjs.map +1 -1
  129. package/dist/grid.js +21 -18
  130. package/dist/grid.js.map +1 -1
  131. package/dist/icon.cjs +1 -1
  132. package/dist/icon.cjs.map +1 -1
  133. package/dist/icon.js +1 -1
  134. package/dist/icon.js.map +1 -1
  135. package/dist/input.cjs +5 -4
  136. package/dist/input.cjs.map +1 -1
  137. package/dist/input.js +14 -8
  138. package/dist/input.js.map +1 -1
  139. package/dist/inputs/combobox/combobox-options.cjs +1 -1
  140. package/dist/inputs/combobox/combobox-options.cjs.map +1 -1
  141. package/dist/inputs/combobox/combobox-options.d.ts.map +1 -1
  142. package/dist/inputs/combobox/combobox-options.js +1 -0
  143. package/dist/inputs/combobox/combobox-options.js.map +1 -1
  144. package/dist/inputs/combobox/combobox.css.cjs +1 -1
  145. package/dist/inputs/combobox/combobox.css.cjs.map +1 -1
  146. package/dist/inputs/combobox/combobox.css.js +1 -1
  147. package/dist/inputs/combobox/combobox.css.js.map +1 -1
  148. package/dist/inputs/combobox/combobox.d.ts +13 -1
  149. package/dist/inputs/combobox/combobox.d.ts.map +1 -1
  150. package/dist/inputs/combobox/combobox.types.d.ts +7 -0
  151. package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
  152. package/dist/inputs/datagrid/datagrid-model.cjs +1 -1
  153. package/dist/inputs/datagrid/datagrid-model.cjs.map +1 -1
  154. package/dist/inputs/datagrid/datagrid-model.d.ts +17 -3
  155. package/dist/inputs/datagrid/datagrid-model.d.ts.map +1 -1
  156. package/dist/inputs/datagrid/datagrid-model.js +93 -70
  157. package/dist/inputs/datagrid/datagrid-model.js.map +1 -1
  158. package/dist/inputs/datagrid/datagrid.css.cjs +1 -1
  159. package/dist/inputs/datagrid/datagrid.css.cjs.map +1 -1
  160. package/dist/inputs/datagrid/datagrid.css.js +1 -1
  161. package/dist/inputs/datagrid/datagrid.css.js.map +1 -1
  162. package/dist/inputs/datagrid/datagrid.d.ts +78 -36
  163. package/dist/inputs/datagrid/datagrid.d.ts.map +1 -1
  164. package/dist/inputs/file-input/file-input-upload.cjs +1 -1
  165. package/dist/inputs/file-input/file-input-upload.cjs.map +1 -1
  166. package/dist/inputs/file-input/file-input-upload.js +1 -1
  167. package/dist/inputs/file-input/file-input-upload.js.map +1 -1
  168. package/dist/inputs/index.d.ts +3 -4
  169. package/dist/inputs/index.d.ts.map +1 -1
  170. package/dist/inputs/input/input.css.cjs +1 -1
  171. package/dist/inputs/input/input.css.cjs.map +1 -1
  172. package/dist/inputs/input/input.css.js +1 -1
  173. package/dist/inputs/input/input.css.js.map +1 -1
  174. package/dist/inputs/input/input.d.ts +3 -0
  175. package/dist/inputs/input/input.d.ts.map +1 -1
  176. package/dist/inputs/select/select.css.cjs +1 -1
  177. package/dist/inputs/select/select.css.cjs.map +1 -1
  178. package/dist/inputs/select/select.css.js +1 -1
  179. package/dist/inputs/select/select.css.js.map +1 -1
  180. package/dist/inputs/select/select.d.ts +5 -0
  181. package/dist/inputs/select/select.d.ts.map +1 -1
  182. package/dist/inputs/shared/field-binding.cjs +1 -1
  183. package/dist/inputs/shared/field-binding.cjs.map +1 -1
  184. package/dist/inputs/shared/field-binding.js +6 -6
  185. package/dist/inputs/shared/field-binding.js.map +1 -1
  186. package/dist/layout/box/box.css.cjs +1 -1
  187. package/dist/layout/box/box.css.cjs.map +1 -1
  188. package/dist/layout/box/box.css.js +1 -1
  189. package/dist/layout/box/box.css.js.map +1 -1
  190. package/dist/layout/box/box.d.ts +3 -3
  191. package/dist/layout/box/box.d.ts.map +1 -1
  192. package/dist/layout/grid/grid.d.ts.map +1 -1
  193. package/dist/layout/navbar/navbar.css.cjs +1 -1
  194. package/dist/layout/navbar/navbar.css.cjs.map +1 -1
  195. package/dist/layout/navbar/navbar.css.js +1 -1
  196. package/dist/layout/navbar/navbar.css.js.map +1 -1
  197. package/dist/layout/navbar/navbar.d.ts +3 -1
  198. package/dist/layout/navbar/navbar.d.ts.map +1 -1
  199. package/dist/layout/sidebar/sidebar.css.cjs +1 -1
  200. package/dist/layout/sidebar/sidebar.css.cjs.map +1 -1
  201. package/dist/layout/sidebar/sidebar.css.js +1 -1
  202. package/dist/layout/sidebar/sidebar.css.js.map +1 -1
  203. package/dist/layout/sidebar/sidebar.d.ts +8 -0
  204. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  205. package/dist/list-item.cjs +6 -5
  206. package/dist/list-item.cjs.map +1 -1
  207. package/dist/list-item.js +23 -17
  208. package/dist/list-item.js.map +1 -1
  209. package/dist/list.cjs +1 -1
  210. package/dist/list.cjs.map +1 -1
  211. package/dist/list.js +1 -1
  212. package/dist/list.js.map +1 -1
  213. package/dist/menu.cjs +1 -1
  214. package/dist/menu.cjs.map +1 -1
  215. package/dist/menu.js +7 -7
  216. package/dist/menu.js.map +1 -1
  217. package/dist/navbar.cjs +2 -2
  218. package/dist/navbar.cjs.map +1 -1
  219. package/dist/navbar.js +91 -87
  220. package/dist/navbar.js.map +1 -1
  221. package/dist/navigation-menu.cjs +1 -1
  222. package/dist/navigation-menu.cjs.map +1 -1
  223. package/dist/navigation-menu.js +2 -2
  224. package/dist/navigation-menu.js.map +1 -1
  225. package/dist/number-input.cjs +1 -1
  226. package/dist/number-input.cjs.map +1 -1
  227. package/dist/number-input.js +1 -1
  228. package/dist/number-input.js.map +1 -1
  229. package/dist/overlay/popover/popover.css.cjs +1 -1
  230. package/dist/overlay/popover/popover.css.cjs.map +1 -1
  231. package/dist/overlay/popover/popover.css.js +1 -1
  232. package/dist/overlay/popover/popover.css.js.map +1 -1
  233. package/dist/overlay/popover/popover.d.ts +1 -0
  234. package/dist/overlay/popover/popover.d.ts.map +1 -1
  235. package/dist/overlay/shared/use-dialog.cjs +1 -1
  236. package/dist/overlay/shared/use-dialog.cjs.map +1 -1
  237. package/dist/overlay/shared/use-dialog.js +1 -1
  238. package/dist/overlay/shared/use-dialog.js.map +1 -1
  239. package/dist/overlay/shared/use-floating-trigger.cjs +1 -1
  240. package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
  241. package/dist/overlay/shared/use-floating-trigger.js +1 -1
  242. package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
  243. package/dist/overlay/tooltip/tooltip.d.ts.map +1 -1
  244. package/dist/popover.cjs +1 -1
  245. package/dist/popover.cjs.map +1 -1
  246. package/dist/popover.js +6 -6
  247. package/dist/popover.js.map +1 -1
  248. package/dist/radio-group.cjs +1 -1
  249. package/dist/radio-group.cjs.map +1 -1
  250. package/dist/radio-group.js +1 -1
  251. package/dist/radio-group.js.map +1 -1
  252. package/dist/radio.cjs +1 -1
  253. package/dist/radio.cjs.map +1 -1
  254. package/dist/radio.js +15 -13
  255. package/dist/radio.js.map +1 -1
  256. package/dist/rating.cjs +1 -1
  257. package/dist/rating.cjs.map +1 -1
  258. package/dist/rating.js +2 -2
  259. package/dist/rating.js.map +1 -1
  260. package/dist/refine.cjs +373 -324
  261. package/dist/refine.cjs.map +1 -1
  262. package/dist/refine.iife.js +382 -333
  263. package/dist/refine.iife.js.map +1 -1
  264. package/dist/refine.js +417 -368
  265. package/dist/refine.js.map +1 -1
  266. package/dist/select.cjs +16 -14
  267. package/dist/select.cjs.map +1 -1
  268. package/dist/select.js +118 -112
  269. package/dist/select.js.map +1 -1
  270. package/dist/shared/types.d.ts +0 -2
  271. package/dist/shared/types.d.ts.map +1 -1
  272. package/dist/sidebar.cjs +28 -23
  273. package/dist/sidebar.cjs.map +1 -1
  274. package/dist/sidebar.js +143 -108
  275. package/dist/sidebar.js.map +1 -1
  276. package/dist/skeleton.cjs +1 -1
  277. package/dist/skeleton.cjs.map +1 -1
  278. package/dist/skeleton.js +11 -9
  279. package/dist/skeleton.js.map +1 -1
  280. package/dist/slider.cjs +1 -1
  281. package/dist/slider.cjs.map +1 -1
  282. package/dist/slider.js +21 -21
  283. package/dist/slider.js.map +1 -1
  284. package/dist/stats.cjs +18 -0
  285. package/dist/stats.cjs.map +1 -0
  286. package/dist/stats.js +88 -0
  287. package/dist/stats.js.map +1 -0
  288. package/dist/stepper.cjs +1 -1
  289. package/dist/stepper.cjs.map +1 -1
  290. package/dist/stepper.js +1 -1
  291. package/dist/stepper.js.map +1 -1
  292. package/dist/styles/mixins/animation.css.cjs +2 -0
  293. package/dist/styles/mixins/animation.css.cjs.map +1 -1
  294. package/dist/styles/mixins/animation.css.d.ts.map +1 -1
  295. package/dist/styles/mixins/animation.css.js +2 -0
  296. package/dist/styles/mixins/animation.css.js.map +1 -1
  297. package/dist/tab-item.cjs +1 -1
  298. package/dist/tab-item.cjs.map +1 -1
  299. package/dist/tab-item.js +3 -2
  300. package/dist/tab-item.js.map +1 -1
  301. package/dist/tabs.cjs +1 -1
  302. package/dist/tabs.cjs.map +1 -1
  303. package/dist/tabs.js +3 -1
  304. package/dist/tabs.js.map +1 -1
  305. package/dist/toast.cjs +8 -8
  306. package/dist/toast.cjs.map +1 -1
  307. package/dist/toast.js +32 -33
  308. package/dist/toast.js.map +1 -1
  309. package/dist/tooltip.cjs +1 -1
  310. package/dist/tooltip.cjs.map +1 -1
  311. package/dist/tooltip.js +2 -2
  312. package/dist/tooltip.js.map +1 -1
  313. package/dist/types/elements.d.ts +207 -0
  314. package/package.json +70 -62
@@ -1 +1 @@
1
- {"version":3,"file":"toast.cjs","names":["#entries","#listeners","#eventListeners","#disposed","#max","#setEntries","#emit","#entry","#update","#scheduleTimer","#clearTimer"],"sources":["../src/feedback/toast/toast.ts"],"sourcesContent":["import '../alert/alert';\nimport { uuid } from '@vielzeug/arsenal/random';\nimport { createPanGesture, type PanGesture } from '@vielzeug/gesture';\nimport { define, getHost, html, onCleanup, onMounted, prop, ref, useEmit } from '@vielzeug/ore';\nimport { computed, signal, watch } from '@vielzeug/ripple';\nimport { warn } from '../../_dev';\nimport { reducedMotionMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './toast.css?inline';\n\n/** Must match toast.css's default opacity transition duration. */\nconst TOAST_EXIT_MS = 300;\n\nexport type OreToastEvents = {\n add: { id: string };\n dismiss: { id: string };\n};\n\nexport type OreToastProps = {\n max?: number;\n position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';\n};\n\n/** Individual toast notification. */\nexport type ToastItem = {\n actions?: Array<{\n color?: ThemeColor;\n label: string;\n onClick?: () => void;\n variant?: 'solid' | 'flat' | 'bordered';\n }>;\n color?: ThemeColor;\n dismissible?: boolean;\n /** Auto-dismiss delay in ms. Set to 0 for persistent toasts (default: 5000). */\n duration?: number;\n heading?: string;\n /** Show message and actions side-by-side (horizontal layout). */\n horizontal?: boolean;\n /** Auto-generated when omitted. */\n id?: string;\n message: string;\n /** Metadata text (for example, a timestamp) shown in the alert meta slot. */\n meta?: string;\n /** Called after the toast is fully dismissed and removed. */\n onDismiss?: () => void;\n rounded?: RoundedSize | '';\n size?: ComponentSize;\n /**\n * Screen-reader announcement urgency. Error-coloured toasts are assertive by\n * default; all other toasts are polite.\n */\n urgency?: 'polite' | 'assertive';\n variant?: 'solid' | 'flat' | 'bordered';\n};\n\ntype ToastPhase = 'entering' | 'active' | 'exiting';\n\ntype ToastTimer = {\n remaining: number;\n startedAt: number;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n\ntype ToastEntry = Required<Pick<ToastItem, 'dismissible' | 'duration' | 'id'>> &\n Omit<ToastItem, 'dismissible' | 'duration' | 'id'> & {\n exitTimeoutId: ReturnType<typeof setTimeout> | null;\n id: string;\n phase: ToastPhase;\n timer: ToastTimer | null;\n };\n\ntype ToastStoreEvent = {\n id: string;\n type: 'add' | 'dismiss';\n};\n\n/**\n * Owns notification data and every timer. Renderers only subscribe to this\n * store; they never expose imperative mutation methods themselves.\n */\nclass ToastStore {\n readonly #entries = signal<ToastEntry[]>([]);\n readonly #listeners = new Set<(entries: ToastEntry[]) => void>();\n readonly #eventListeners = new Set<(event: ToastStoreEvent) => void>();\n #disposed = false;\n #max = 5;\n\n add(item: ToastItem): string {\n if (this.#disposed) return item.id ?? uuid();\n\n const id = item.id ?? uuid();\n const active = this.#entries.value.filter((entry) => entry.phase !== 'exiting');\n const overflow = active.length - (this.#max - 1);\n\n if (overflow > 0) {\n for (const entry of active.slice(0, overflow)) this.dismiss(entry.id);\n }\n\n const entry: ToastEntry = {\n dismissible: true,\n duration: 5000,\n ...item,\n exitTimeoutId: null,\n id,\n phase: 'entering',\n timer: null,\n };\n\n this.#setEntries([...this.#entries.value, entry]);\n this.#emit({ id, type: 'add' });\n\n requestAnimationFrame(() => {\n if (this.#entry(id)?.phase === 'entering') this.#update(id, { phase: 'active' });\n });\n\n if (entry.duration > 0) this.#scheduleTimer(id, entry.duration);\n\n return id;\n }\n\n clear(): void {\n for (const entry of this.#entries.value) {\n if (entry.phase !== 'exiting') this.dismiss(entry.id);\n }\n }\n\n dispose(): void {\n if (this.#disposed) return;\n\n this.#disposed = true;\n\n for (const entry of this.#entries.value) {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n }\n\n this.#setEntries([]);\n this.#listeners.clear();\n this.#eventListeners.clear();\n }\n\n dismiss(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || entry.phase === 'exiting' || this.#disposed) return;\n\n this.#update(id, { ...this.#clearTimer(entry), phase: 'exiting' });\n this.scheduleFinalization(id, TOAST_EXIT_MS + 50);\n }\n\n finalize(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n this.#setEntries(this.#entries.value.filter((candidate) => candidate.id !== id));\n entry.onDismiss?.();\n this.#emit({ id, type: 'dismiss' });\n }\n\n pauseTimers(): void {\n if (this.#disposed) return;\n\n this.#setEntries(\n this.#entries.value.map((entry) => {\n if (!entry.timer) return entry;\n\n clearTimeout(entry.timer.timeoutId);\n\n return {\n ...entry,\n timer: {\n ...entry.timer,\n remaining: Math.max(0, entry.timer.remaining - (Date.now() - entry.timer.startedAt)),\n },\n };\n }),\n );\n }\n\n resumeTimers(): void {\n if (this.#disposed) return;\n\n for (const entry of this.#entries.value) {\n if (entry.phase === 'active' && entry.timer && entry.timer.remaining > 0) {\n this.#scheduleTimer(entry.id, entry.timer.remaining);\n }\n }\n }\n\n scheduleFinalization(id: string, delay: number): void {\n const entry = this.#entry(id);\n\n if (entry?.phase !== 'exiting' || this.#disposed) return;\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n const exitTimeoutId = setTimeout(() => this.finalize(id), delay);\n\n this.#update(id, { exitTimeoutId });\n }\n\n setMax(max: number | undefined): void {\n if (max != null) this.#max = Math.max(1, max);\n }\n\n subscribe(listener: (entries: ToastEntry[]) => void): () => void {\n listener(this.#entries.value);\n this.#listeners.add(listener);\n\n return () => this.#listeners.delete(listener);\n }\n\n subscribeEvents(listener: (event: ToastStoreEvent) => void): () => void {\n this.#eventListeners.add(listener);\n\n return () => this.#eventListeners.delete(listener);\n }\n\n update(id: string, updates: Partial<ToastItem>): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n const cleared = updates.duration !== undefined ? this.#clearTimer(entry) : entry;\n\n this.#update(id, { ...cleared, ...updates, id });\n\n if (updates.duration !== undefined && updates.duration > 0) this.#scheduleTimer(id, updates.duration);\n }\n\n #clearTimer(entry: ToastEntry): ToastEntry {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n return { ...entry, timer: null };\n }\n\n #emit(event: ToastStoreEvent): void {\n for (const listener of this.#eventListeners) listener(event);\n }\n\n #entry(id: string): ToastEntry | undefined {\n return this.#entries.value.find((entry) => entry.id === id);\n }\n\n #scheduleTimer(id: string, remaining: number): void {\n if (remaining <= 0 || this.#disposed) return;\n\n const timeoutId = setTimeout(() => this.dismiss(id), remaining);\n\n this.#update(id, { timer: { remaining, startedAt: Date.now(), timeoutId } });\n }\n\n #setEntries(entries: ToastEntry[]): void {\n this.#entries.value = entries;\n for (const listener of this.#listeners) listener(entries);\n }\n\n #update(id: string, patch: Partial<ToastEntry>): void {\n this.#setEntries(this.#entries.value.map((entry) => (entry.id === id ? { ...entry, ...patch } : entry)));\n }\n}\n\ntype ToastHostBinding = {\n bind: (store: ToastStore) => void;\n unbind: () => void;\n};\n\nconst hostBindings = new WeakMap<HTMLElement, ToastHostBinding>();\nconst hostStores = new WeakMap<HTMLElement, ToastStore>();\n\nconst bindToastHost = (host: HTMLElement, store: ToastStore): void => {\n hostStores.set(host, store);\n hostBindings.get(host)?.bind(store);\n};\n\n/** Renders the action buttons for a toast entry. */\nfunction renderToastActions(entry: ToastEntry, dismiss: () => void) {\n if (!entry.actions?.length) return '';\n\n return html`\n <div slot=\"actions\" class=\"toast-actions\">\n ${entry.actions.map(\n (action) => html`\n <ore-button\n size=\"sm\"\n color=${action.color || entry.color || 'primary'}\n variant=${action.variant || 'solid'}\n @click=${() => {\n action.onClick?.();\n dismiss();\n }}>\n ${action.label}\n </ore-button>\n `,\n )}\n </div>\n `;\n}\n\nexport const TOAST_TAG = 'ore-toast' as const;\n\n/**\n * Declarative toast host. It subscribes to the service for its scope and\n * renders notifications, but has no imperative mutation API of its own.\n *\n * @element ore-toast\n *\n * @attr {string} position - Stack placement.\n * @attr {number} max - Maximum live notifications for the scoped service.\n */\ndefine<OreToastProps>(TOAST_TAG, {\n props: {\n max: prop.number(5),\n position: prop.oneOf(\n ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'] as const,\n 'bottom-right',\n ),\n },\n setup() {\n const el = getHost() as HTMLElement;\n const emit = useEmit<OreToastEvents>();\n const containerRef = ref<HTMLDivElement>();\n const entries = signal<ToastEntry[]>([]);\n const hoverPaused = signal(false);\n const focusPaused = signal(false);\n const paused = computed(() => hoverPaused.value || focusPaused.value);\n const swipeControls = new Map<string, { element: HTMLElement; gesture: PanGesture }>();\n const exiting = new Map<string, () => void>();\n const swiping = new Set<string>();\n let pendingSyncFrame: number | undefined;\n let store: ToastStore | null = null;\n let unsubscribeEntries = () => {};\n let unsubscribeEvents = () => {};\n\n const getInner = (wrapper: HTMLElement): HTMLElement | null => {\n return wrapper.querySelector<HTMLElement>('.toast-inner');\n };\n\n const clearExitListener = (id: string): void => {\n exiting.get(id)?.();\n exiting.delete(id);\n };\n\n const finalizeSwipe = (id: string): void => {\n swiping.delete(id);\n store?.finalize(id);\n };\n\n const createToastSwipe = (id: string, wrapper: HTMLElement): PanGesture => {\n const isDismissible = (): boolean => entries.value.find((entry) => entry.id === id)?.dismissible ?? true;\n const reset = (): void => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = '';\n inner.style.transform = '';\n inner.style.opacity = '';\n };\n\n return createPanGesture(wrapper, {\n axis: 'x',\n disabled: () => !isDismissible(),\n onEnd: ({ distance, reason }) => {\n if (reason !== 'release' || Math.abs(distance) < 48) {\n reset();\n\n return;\n }\n\n const inner = getInner(wrapper);\n\n if (!inner || !store) return;\n\n swiping.add(id);\n\n store.dismiss(id);\n\n const finish = () => finalizeSwipe(id);\n\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n inner.style.opacity = '0';\n finish();\n\n return;\n }\n\n const direction = distance >= 0 ? 1 : -1;\n\n inner.style.transition = 'transform 0.22s ease-out, opacity 0.22s ease-out';\n void inner.offsetWidth;\n inner.style.transform = `translateX(${direction * 120}%)`;\n inner.style.opacity = '0';\n\n const onTransitionEnd = (transition: TransitionEvent) => {\n if (transition.target !== inner || transition.propertyName !== 'transform') return;\n\n inner.removeEventListener('transitionend', onTransitionEnd);\n finish();\n };\n\n inner.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, 300);\n },\n onMove: ({ distance }) => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = 'none';\n inner.style.transform = `translateX(${distance}px)`;\n inner.style.opacity = String(Math.max(0, 1 - Math.abs(distance) / 200));\n },\n pointerCapture: false,\n shouldStart: (event) =>\n !event\n .composedPath()\n .some((node) => node instanceof Element && node.matches('button, a, input, select, textarea, ore-button')),\n });\n };\n\n const beginExit = (id: string): void => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n requestAnimationFrame(() => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n const inner = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${id}\"] .toast-inner`);\n\n if (!inner) {\n store.scheduleFinalization(id, TOAST_EXIT_MS);\n\n return;\n }\n\n void inner.offsetHeight;\n\n const duration = parseFloat(getComputedStyle(inner).transitionDuration) * 1000;\n const exitMs = Number.isFinite(duration) && duration > 0 ? duration : TOAST_EXIT_MS;\n const onTransitionEnd = (event: TransitionEvent) => {\n const wrapper = (event.target as HTMLElement | null)?.closest?.(`[data-toast-id=\"${id}\"]`);\n\n if (!wrapper) return;\n\n clearExitListener(id);\n store?.finalize(id);\n };\n const remove = () => containerRef.value?.removeEventListener('transitionend', onTransitionEnd);\n\n exiting.set(id, remove);\n containerRef.value?.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, exitMs + 50);\n });\n };\n\n const syncControls = (): void => {\n const currentIds = new Set(entries.value.map((entry) => entry.id));\n\n for (const [id, control] of swipeControls) {\n if (!currentIds.has(id)) {\n control.gesture.dispose();\n\n swipeControls.delete(id);\n clearExitListener(id);\n swiping.delete(id);\n }\n }\n\n for (const entry of entries.value) {\n const wrapper = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${entry.id}\"]`);\n const control = swipeControls.get(entry.id);\n\n if (wrapper && control?.element !== wrapper) {\n control?.gesture.dispose();\n swipeControls.set(entry.id, { element: wrapper, gesture: createToastSwipe(entry.id, wrapper) });\n }\n\n if (entry.phase === 'exiting') beginExit(entry.id);\n }\n };\n\n const scheduleSyncControls = (): void => {\n syncControls();\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n pendingSyncFrame = requestAnimationFrame(() => {\n pendingSyncFrame = undefined;\n syncControls();\n });\n };\n\n watch(entries, scheduleSyncControls);\n watch(paused, (isPaused) => {\n if (isPaused) store?.pauseTimers();\n else store?.resumeTimers();\n });\n\n const bind = (nextStore: ToastStore): void => {\n if (store === nextStore) return;\n\n unsubscribeEntries();\n\n unsubscribeEvents();\n store = nextStore;\n unsubscribeEntries = store.subscribe((nextEntries) => {\n entries.value = nextEntries;\n });\n unsubscribeEvents = store.subscribeEvents((event) => emit(event.type, { id: event.id }));\n\n if (paused.value) store.pauseTimers();\n };\n\n const renderEntry = (entry: ToastEntry) => {\n const dismiss = () => store?.dismiss(entry.id);\n\n return html`\n <div\n class=\"toast-wrapper\"\n data-toast-id=${entry.id}\n part=\"toast-wrapper\">\n <div class=\"${() => `toast-inner${entry.phase !== 'active' ? ` ${entry.phase}` : ''}`}\" part=\"toast-inner\">\n <ore-alert\n color=${entry.color || (entry.urgency === 'assertive' ? 'error' : 'primary')}\n variant=${entry.variant || 'solid'}\n size=${entry.size || 'md'}\n rounded=${entry.rounded || 'md'}\n ?horizontal=${entry.horizontal}\n heading=${entry.heading || ''}\n ?dismissible=${entry.dismissible}\n @dismiss=${dismiss}>\n ${\n entry.meta\n ? html`\n <span slot=\"meta\">${entry.meta}</span>\n `\n : ''\n }\n ${entry.message} ${renderToastActions(entry, dismiss)}\n </ore-alert>\n </div>\n </div>\n `;\n };\n\n onMounted(() => {\n hostBindings.set(el, {\n bind,\n unbind() {\n unsubscribeEntries();\n unsubscribeEvents();\n store = null;\n entries.value = [];\n },\n });\n\n const boundStore = hostStores.get(el);\n\n if (boundStore) bind(boundStore);\n });\n\n onCleanup(() => {\n hostBindings.get(el)?.unbind();\n\n hostBindings.delete(el);\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n for (const control of swipeControls.values()) control.gesture.dispose();\n swipeControls.clear();\n for (const id of exiting.keys()) clearExitListener(id);\n });\n\n const urgencyOf = (entry: ToastEntry) => entry.urgency ?? (entry.color === 'error' ? 'assertive' : 'polite');\n const politeEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'polite'));\n const assertiveEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'assertive'));\n\n return html`\n <div\n class=\"toast-container\"\n ref=${containerRef}\n @pointerenter=${() => {\n hoverPaused.value = true;\n el.classList.add('hovered');\n }}\n @pointerleave=${() => {\n hoverPaused.value = false;\n el.classList.remove('hovered');\n }}\n @focusin=${() => {\n focusPaused.value = true;\n }}\n @focusout=${() => {\n focusPaused.value = false;\n }}\n part=\"container\">\n <div\n role=\"region\"\n aria-live=\"polite\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Notifications\"\n class=\"toast-live-region\">\n ${() => politeEntries.value.map(renderEntry)}\n </div>\n <div\n role=\"region\"\n aria-live=\"assertive\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Critical notifications\"\n class=\"toast-live-region\">\n ${() => assertiveEntries.value.map(renderEntry)}\n </div>\n <slot></slot>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n\nexport type ToastServiceConfig = OreToastProps;\n\nexport interface ToastService {\n add(item: ToastItem): string;\n clear(): void;\n configure(config: ToastServiceConfig): void;\n dismiss(id: string): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n error(message: string, opts?: Partial<ToastItem>): string;\n info(message: string, opts?: Partial<ToastItem>): string;\n promise<T>(\n promise: Promise<T>,\n messages: {\n error: string | ((err: unknown) => string);\n loading: string;\n success: string | ((data: T) => string);\n },\n ): Promise<T>;\n success(message: string, opts?: Partial<ToastItem>): string;\n update(id: string, updates: Partial<ToastItem>): void;\n warning(message: string, opts?: Partial<ToastItem>): string;\n [Symbol.dispose](): void;\n}\n\nconst services = new WeakMap<ParentNode, ToastService>();\n\n/**\n * Creates a scoped toast service. The service owns its notification store and\n * binds it to the declarative `<ore-toast>` host inside `root`, creating that\n * host lazily when notifications are first requested.\n */\nexport function createToastService(root: ParentNode = document.body): ToastService {\n const existing = services.get(root);\n\n if (existing) return existing;\n\n const store = new ToastStore();\n const disposalController = new AbortController();\n let disposed = false;\n let configured = false;\n let pendingConfig: ToastServiceConfig | null = null;\n let host: HTMLElement | null = null;\n\n const assertActive = (): boolean => !disposed;\n const rootNode = root as Element | Document | ShadowRoot;\n const getHost = (): HTMLElement | null => {\n if (!assertActive()) return null;\n\n if (host?.isConnected) return host;\n\n host = rootNode.querySelector<HTMLElement>(TOAST_TAG);\n\n if (!host) {\n host = document.createElement(TOAST_TAG);\n\n if (pendingConfig?.position) host.setAttribute('position', pendingConfig.position);\n\n if (pendingConfig?.max != null) host.setAttribute('max', String(pendingConfig.max));\n\n rootNode.appendChild(host);\n }\n\n if (pendingConfig?.max != null) store.setMax(pendingConfig.max);\n else {\n const max = Number(host.getAttribute('max'));\n\n if (Number.isFinite(max) && max > 0) store.setMax(max);\n }\n\n pendingConfig = null;\n configured = true;\n bindToastHost(host, store);\n\n return host;\n };\n const ensureHost = (): boolean => Boolean(getHost());\n\n const service: ToastService = {\n add(item) {\n if (!ensureHost()) return item.id ?? uuid();\n\n return store.add(item);\n },\n\n clear() {\n if (ensureHost()) store.clear();\n },\n\n configure(config) {\n if (configured) {\n warn('toast.configure() called after the container was already created; options ignored.');\n\n return;\n }\n\n pendingConfig = { ...pendingConfig, ...config };\n },\n\n dismiss(id) {\n if (ensureHost()) store.dismiss(id);\n },\n\n get disposalSignal() {\n return disposalController.signal;\n },\n\n dispose() {\n if (disposed) return;\n\n disposed = true;\n\n disposalController.abort();\n\n store.dispose();\n\n if (services.get(root) === service) services.delete(root);\n },\n\n get disposed() {\n return disposed;\n },\n\n error(message, opts) {\n return service.add({ color: 'error', ...opts, message });\n },\n\n info(message, opts) {\n return service.add({ color: 'info', ...opts, message });\n },\n\n async promise(promise, messages) {\n const id = service.add({ color: 'primary', dismissible: false, duration: 0, message: messages.loading });\n\n try {\n const data = await promise;\n\n service.update(id, {\n color: 'success',\n dismissible: true,\n duration: 5000,\n message: typeof messages.success === 'function' ? messages.success(data) : messages.success,\n });\n\n return data;\n } catch (err) {\n service.update(id, {\n color: 'error',\n dismissible: true,\n duration: 5000,\n message: typeof messages.error === 'function' ? messages.error(err) : messages.error,\n });\n throw err;\n }\n },\n\n success(message, opts) {\n return service.add({ color: 'success', ...opts, message });\n },\n\n [Symbol.dispose]() {\n service.dispose();\n },\n\n update(id, updates) {\n if (ensureHost()) store.update(id, updates);\n },\n\n warning(message, opts) {\n return service.add({ color: 'warning', ...opts, message });\n },\n };\n\n services.set(root, service);\n\n return service;\n}\n\n/** Singleton service backed by a lazily created host in `document.body`. */\nexport const toast: ToastService = createToastService();\n"],"mappings":"sUAWA,IAAM,EAAgB,IAqEhB,EAAN,KAAiB,CACf,IAAA,EAAoB,EAAA,OAAA,CAAqB,CAAC,CAAC,EAC3C,GAAsB,IAAI,IAC1B,GAA2B,IAAI,IAC/B,GAAY,GACZ,GAAO,EAEP,IAAI,EAAyB,CAC3B,GAAI,KAAKG,GAAW,OAAO,EAAK,KAAA,EAAM,EAAA,KAAA,CAAK,EAE3C,IAAM,EAAK,EAAK,KAAA,EAAM,EAAA,KAAA,CAAK,EACrB,EAAS,KAAKH,GAAS,MAAM,OAAQ,GAAU,EAAM,QAAU,SAAS,EACxE,EAAW,EAAO,QAAU,KAAKI,GAAO,GAE9C,GAAI,EAAW,EACb,IAAK,IAAM,KAAS,EAAO,MAAM,EAAG,CAAQ,EAAG,KAAK,QAAQ,EAAM,EAAE,EAGtE,IAAM,EAAoB,CACxB,YAAa,GACb,SAAU,IACV,GAAG,EACH,cAAe,KACf,KACA,MAAO,WACP,MAAO,IACT,EAWA,OATA,KAAKC,GAAY,CAAC,GAAG,KAAKL,GAAS,MAAO,CAAK,CAAC,EAChD,KAAKM,GAAM,CAAE,KAAI,KAAM,KAAM,CAAC,EAE9B,0BAA4B,CACtB,KAAKC,GAAO,CAAE,CAAC,EAAE,QAAU,YAAY,KAAKC,GAAQ,EAAI,CAAE,MAAO,QAAS,CAAC,CACjF,CAAC,EAEG,EAAM,SAAW,GAAG,KAAKC,GAAe,EAAI,EAAM,QAAQ,EAEvD,CACT,CAEA,OAAc,CACZ,IAAK,IAAM,KAAS,KAAKT,GAAS,MAC5B,EAAM,QAAU,WAAW,KAAK,QAAQ,EAAM,EAAE,CAExD,CAEA,SAAgB,CACV,SAAKG,GAET,MAAKA,GAAY,GAEjB,IAAK,IAAM,KAAS,KAAKH,GAAS,MAC5B,EAAM,OAAO,aAAa,EAAM,MAAM,SAAS,EAE/C,EAAM,eAAe,aAAa,EAAM,aAAa,EAG3D,KAAKK,GAAY,CAAC,CAAC,EACnB,KAAKJ,GAAW,MAAM,EACtB,KAAKC,GAAgB,MAAM,CAVV,CAWnB,CAEA,QAAQ,EAAkB,CACxB,IAAM,EAAQ,KAAKK,GAAO,CAAE,EAExB,CAAC,GAAS,EAAM,QAAU,WAAa,KAAKJ,KAEhD,KAAKK,GAAQ,EAAI,CAAE,GAAG,KAAKE,GAAY,CAAK,EAAG,MAAO,SAAU,CAAC,EACjE,KAAK,qBAAqB,EAAI,GAAkB,EAClD,CAEA,SAAS,EAAkB,CACzB,IAAM,EAAQ,KAAKH,GAAO,CAAE,EAExB,CAAC,GAAS,KAAKJ,KAEf,EAAM,OAAO,aAAa,EAAM,MAAM,SAAS,EAE/C,EAAM,eAAe,aAAa,EAAM,aAAa,EAEzD,KAAKE,GAAY,KAAKL,GAAS,MAAM,OAAQ,GAAc,EAAU,KAAO,CAAE,CAAC,EAC/E,EAAM,YAAY,EAClB,KAAKM,GAAM,CAAE,KAAI,KAAM,SAAU,CAAC,EACpC,CAEA,aAAoB,CACd,KAAKH,IAET,KAAKE,GACH,KAAKL,GAAS,MAAM,IAAK,GAClB,EAAM,OAEX,aAAa,EAAM,MAAM,SAAS,EAE3B,CACL,GAAG,EACH,MAAO,CACL,GAAG,EAAM,MACT,UAAW,KAAK,IAAI,EAAG,EAAM,MAAM,WAAa,KAAK,IAAI,EAAI,EAAM,MAAM,UAAU,CACrF,CACF,GAVyB,CAW1B,CACH,CACF,CAEA,cAAqB,CACf,SAAKG,GAET,IAAK,IAAM,KAAS,KAAKH,GAAS,MAC5B,EAAM,QAAU,UAAY,EAAM,OAAS,EAAM,MAAM,UAAY,GACrE,KAAKS,GAAe,EAAM,GAAI,EAAM,MAAM,SAAS,CAGzD,CAEA,qBAAqB,EAAY,EAAqB,CACpD,IAAM,EAAQ,KAAKF,GAAO,CAAE,EAE5B,GAAI,GAAO,QAAU,WAAa,KAAKJ,GAAW,OAE9C,EAAM,eAAe,aAAa,EAAM,aAAa,EAEzD,IAAM,EAAgB,eAAiB,KAAK,SAAS,CAAE,EAAG,CAAK,EAE/D,KAAKK,GAAQ,EAAI,CAAE,eAAc,CAAC,CACpC,CAEA,OAAO,EAA+B,CAChC,GAAO,OAAM,KAAKJ,GAAO,KAAK,IAAI,EAAG,CAAG,EAC9C,CAEA,UAAU,EAAuD,CAI/D,OAHA,EAAS,KAAKJ,GAAS,KAAK,EAC5B,KAAKC,GAAW,IAAI,CAAQ,MAEf,KAAKA,GAAW,OAAO,CAAQ,CAC9C,CAEA,gBAAgB,EAAwD,CAGtE,OAFA,KAAKC,GAAgB,IAAI,CAAQ,MAEpB,KAAKA,GAAgB,OAAO,CAAQ,CACnD,CAEA,OAAO,EAAY,EAAmC,CACpD,IAAM,EAAQ,KAAKK,GAAO,CAAE,EAE5B,GAAI,CAAC,GAAS,KAAKJ,GAAW,OAE9B,IAAM,EAAU,EAAQ,WAAa,IAAA,GAAsC,EAA1B,KAAKO,GAAY,CAAK,EAEvE,KAAKF,GAAQ,EAAI,CAAE,GAAG,EAAS,GAAG,EAAS,IAAG,CAAC,EAE3C,EAAQ,WAAa,IAAA,IAAa,EAAQ,SAAW,GAAG,KAAKC,GAAe,EAAI,EAAQ,QAAQ,CACtG,CAEA,GAAY,EAA+B,CAGzC,OAFI,EAAM,OAAO,aAAa,EAAM,MAAM,SAAS,EAE5C,CAAE,GAAG,EAAO,MAAO,IAAK,CACjC,CAEA,GAAM,EAA8B,CAClC,IAAK,IAAM,KAAY,KAAKP,GAAiB,EAAS,CAAK,CAC7D,CAEA,GAAO,EAAoC,CACzC,OAAO,KAAKF,GAAS,MAAM,KAAM,GAAU,EAAM,KAAO,CAAE,CAC5D,CAEA,GAAe,EAAY,EAAyB,CAClD,GAAI,GAAa,GAAK,KAAKG,GAAW,OAEtC,IAAM,EAAY,eAAiB,KAAK,QAAQ,CAAE,EAAG,CAAS,EAE9D,KAAKK,GAAQ,EAAI,CAAE,MAAO,CAAE,YAAW,UAAW,KAAK,IAAI,EAAG,WAAU,CAAE,CAAC,CAC7E,CAEA,GAAY,EAA6B,CACvC,KAAKR,GAAS,MAAQ,EACtB,IAAK,IAAM,KAAY,KAAKC,GAAY,EAAS,CAAO,CAC1D,CAEA,GAAQ,EAAY,EAAkC,CACpD,KAAKI,GAAY,KAAKL,GAAS,MAAM,IAAK,GAAW,EAAM,KAAO,EAAK,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CAAM,CAAC,CACzG,CACF,EAOM,EAAe,IAAI,QACnB,EAAa,IAAI,QAEjB,GAAiB,EAAmB,IAA4B,CACpE,EAAW,IAAI,EAAM,CAAK,EAC1B,EAAa,IAAI,CAAI,CAAC,EAAE,KAAK,CAAK,CACpC,EAGA,SAAS,EAAmB,EAAmB,EAAqB,CAGlE,OAFK,EAAM,SAAS,OAEb,EAAA,IAAI;;QAEL,EAAM,QAAQ,IACb,GAAW,EAAA,IAAI;;;oBAGJ,EAAO,OAAS,EAAM,OAAS,UAAU;sBACvC,EAAO,SAAW,QAAQ;yBACrB,CACb,EAAO,UAAU,EACjB,EAAQ,CACV,EAAE;cACA,EAAO,MAAM;;SAGrB,EAAE;;IAjB6B,EAoBrC,CAEA,IAAa,EAAY,aAWzB,EAAA,EAAA,OAAA,CAAsB,EAAW,CAC/B,MAAO,CACL,IAAK,EAAA,KAAK,OAAO,CAAC,EAClB,SAAU,EAAA,KAAK,MACb,CAAC,WAAY,aAAc,YAAa,cAAe,gBAAiB,cAAc,EACtF,cACF,CACF,EACA,OAAQ,CACN,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACb,GAAA,EAAO,EAAA,QAAA,CAAwB,EAC/B,GAAA,EAAe,EAAA,IAAA,CAAoB,EACnC,GAAA,EAAU,EAAA,OAAA,CAAqB,CAAC,CAAC,EACjC,GAAA,EAAc,EAAA,OAAA,CAAO,EAAK,EAC1B,GAAA,EAAc,EAAA,OAAA,CAAO,EAAK,EAC1B,GAAA,EAAS,EAAA,SAAA,KAAe,EAAY,OAAS,EAAY,KAAK,EAC9D,EAAgB,IAAI,IACpB,EAAU,IAAI,IACd,EAAU,IAAI,IAChB,EACA,EAA2B,KAC3B,MAA2B,CAAC,EAC5B,MAA0B,CAAC,EAEzB,EAAY,GACT,EAAQ,cAA2B,cAAc,EAGpD,EAAqB,GAAqB,CAC9C,EAAQ,IAAI,CAAE,CAAC,GAAG,EAClB,EAAQ,OAAO,CAAE,CACnB,EAEM,EAAiB,GAAqB,CAC1C,EAAQ,OAAO,CAAE,EACjB,GAAO,SAAS,CAAE,CACpB,EAEM,GAAoB,EAAY,IAAqC,CACzE,IAAM,MAA+B,EAAQ,MAAM,KAAM,GAAU,EAAM,KAAO,CAAE,CAAC,EAAE,aAAe,GAC9F,MAAoB,CACxB,IAAM,EAAQ,EAAS,CAAO,EAEzB,IAEL,EAAM,MAAM,WAAa,GACzB,EAAM,MAAM,UAAY,GACxB,EAAM,MAAM,QAAU,GACxB,EAEA,OAAA,EAAO,EAAA,iBAAA,CAAiB,EAAS,CAC/B,KAAM,IACN,aAAgB,CAAC,EAAc,EAC/B,OAAQ,CAAE,WAAU,YAAa,CAC/B,GAAI,IAAW,WAAa,KAAK,IAAI,CAAQ,EAAI,GAAI,CACnD,EAAM,EAEN,MACF,CAEA,IAAM,EAAQ,EAAS,CAAO,EAE9B,GAAI,CAAC,GAAS,CAAC,EAAO,OAEtB,EAAQ,IAAI,CAAE,EAEd,EAAM,QAAQ,CAAE,EAEhB,IAAM,MAAe,EAAc,CAAE,EAErC,GAAI,OAAO,WAAW,kCAAkC,CAAC,CAAC,QAAS,CACjE,EAAM,MAAM,QAAU,IACtB,EAAO,EAEP,MACF,CAEA,IAAM,EAAY,GAAY,EAAI,EAAI,GAEtC,EAAM,MAAM,WAAa,mDACzB,EAAW,YACX,EAAM,MAAM,UAAY,cAAc,EAAY,IAAI,IACtD,EAAM,MAAM,QAAU,IAEtB,IAAM,EAAmB,GAAgC,CACnD,EAAW,SAAW,GAAS,EAAW,eAAiB,cAE/D,EAAM,oBAAoB,gBAAiB,CAAe,EAC1D,EAAO,EACT,EAEA,EAAM,iBAAiB,gBAAiB,CAAe,EACvD,EAAM,qBAAqB,EAAI,GAAG,CACpC,EACA,QAAS,CAAE,cAAe,CACxB,IAAM,EAAQ,EAAS,CAAO,EAEzB,IAEL,EAAM,MAAM,WAAa,OACzB,EAAM,MAAM,UAAY,cAAc,EAAS,KAC/C,EAAM,MAAM,QAAU,OAAO,KAAK,IAAI,EAAG,EAAI,KAAK,IAAI,CAAQ,EAAI,GAAG,CAAC,EACxE,EACA,eAAgB,GAChB,YAAc,GACZ,CAAC,EACE,aAAa,CAAC,CACd,KAAM,GAAS,aAAgB,SAAW,EAAK,QAAQ,gDAAgD,CAAC,CAC/G,CAAC,CACH,EAEM,EAAa,GAAqB,CAClC,CAAC,GAAS,EAAQ,IAAI,CAAE,GAAK,EAAQ,IAAI,CAAE,GAE/C,0BAA4B,CAC1B,GAAI,CAAC,GAAS,EAAQ,IAAI,CAAE,GAAK,EAAQ,IAAI,CAAE,EAAG,OAElD,IAAM,EAAQ,EAAa,OAAO,cAA2B,mBAAmB,EAAG,gBAAgB,EAEnG,GAAI,CAAC,EAAO,CACV,EAAM,qBAAqB,EAAI,CAAa,EAE5C,MACF,CAEA,EAAW,aAEX,IAAM,EAAW,WAAW,iBAAiB,CAAK,CAAC,CAAC,kBAAkB,EAAI,IACpE,EAAS,OAAO,SAAS,CAAQ,GAAK,EAAW,EAAI,EAAW,EAChE,EAAmB,GAA2B,CACjC,EAAM,QAA+B,UAAU,mBAAmB,EAAG,GAAG,IAIzF,EAAkB,CAAE,EACpB,GAAO,SAAS,CAAE,EACpB,EAGA,EAAQ,IAAI,MAFS,EAAa,OAAO,oBAAoB,gBAAiB,CAAe,CAEvE,EACtB,EAAa,OAAO,iBAAiB,gBAAiB,CAAe,EACrE,EAAM,qBAAqB,EAAI,EAAS,EAAE,CAC5C,CAAC,CACH,EAEM,MAA2B,CAC/B,IAAM,EAAa,IAAI,IAAI,EAAQ,MAAM,IAAK,GAAU,EAAM,EAAE,CAAC,EAEjE,IAAK,GAAM,CAAC,EAAI,KAAY,EACrB,EAAW,IAAI,CAAE,IACpB,EAAQ,QAAQ,QAAQ,EAExB,EAAc,OAAO,CAAE,EACvB,EAAkB,CAAE,EACpB,EAAQ,OAAO,CAAE,GAIrB,IAAK,IAAM,KAAS,EAAQ,MAAO,CACjC,IAAM,EAAU,EAAa,OAAO,cAA2B,mBAAmB,EAAM,GAAG,GAAG,EACxF,EAAU,EAAc,IAAI,EAAM,EAAE,EAEtC,GAAW,GAAS,UAAY,IAClC,GAAS,QAAQ,QAAQ,EACzB,EAAc,IAAI,EAAM,GAAI,CAAE,QAAS,EAAS,QAAS,EAAiB,EAAM,GAAI,CAAO,CAAE,CAAC,GAG5F,EAAM,QAAU,WAAW,EAAU,EAAM,EAAE,CACnD,CACF,GAaA,EAAA,EAAA,MAAA,CAAM,MAXmC,CACvC,EAAa,EAET,IAAqB,IAAA,IAAW,qBAAqB,CAAgB,EAEzE,EAAmB,0BAA4B,CAC7C,EAAmB,IAAA,GACnB,EAAa,CACf,CAAC,CACH,CAEmC,GACnC,EAAA,EAAA,MAAA,CAAM,EAAS,GAAa,CACtB,EAAU,GAAO,YAAY,EAC5B,GAAO,aAAa,CAC3B,CAAC,EAED,IAAM,EAAQ,GAAgC,CACxC,IAAU,IAEd,EAAmB,EAEnB,EAAkB,EAClB,EAAQ,EACR,EAAqB,EAAM,UAAW,GAAgB,CACpD,EAAQ,MAAQ,CAClB,CAAC,EACD,EAAoB,EAAM,gBAAiB,GAAU,EAAK,EAAM,KAAM,CAAE,GAAI,EAAM,EAAG,CAAC,CAAC,EAEnF,EAAO,OAAO,EAAM,YAAY,EACtC,EAEM,EAAe,GAAsB,CACzC,IAAM,MAAgB,GAAO,QAAQ,EAAM,EAAE,EAE7C,MAAO,GAAA,IAAI;;;0BAGS,EAAM,GAAG;;4BAEL,cAAc,EAAM,QAAU,SAA+B,GAApB,IAAI,EAAM,UAAe;;sBAE1E,EAAM,QAAU,EAAM,UAAY,YAAc,QAAU,WAAW;wBACnE,EAAM,SAAW,QAAQ;qBAC5B,EAAM,MAAQ,KAAK;wBAChB,EAAM,SAAW,KAAK;4BAClB,EAAM,WAAW;wBACrB,EAAM,SAAW,GAAG;6BACf,EAAM,YAAY;yBACtB,EAAQ;gBAEjB,EAAM,KACF,EAAA,IAAI;0CACkB,EAAM,KAAK;sBAEjC,GACL;gBACC,EAAM,QAAQ,GAAG,EAAmB,EAAO,CAAO,EAAE;;;;OAKhE,GAEA,EAAA,EAAA,UAAA,KAAgB,CACd,EAAa,IAAI,EAAI,CACnB,OACA,QAAS,CACP,EAAmB,EACnB,EAAkB,EAClB,EAAQ,KACR,EAAQ,MAAQ,CAAC,CACnB,CACF,CAAC,EAED,IAAM,EAAa,EAAW,IAAI,CAAE,EAEhC,GAAY,EAAK,CAAU,CACjC,CAAC,GAED,EAAA,EAAA,UAAA,KAAgB,CACd,EAAa,IAAI,CAAE,CAAC,EAAE,OAAO,EAE7B,EAAa,OAAO,CAAE,EAElB,IAAqB,IAAA,IAAW,qBAAqB,CAAgB,EAEzE,IAAK,IAAM,KAAW,EAAc,OAAO,EAAG,EAAQ,QAAQ,QAAQ,EACtE,EAAc,MAAM,EACpB,IAAK,IAAM,KAAM,EAAQ,KAAK,EAAG,EAAkB,CAAE,CACvD,CAAC,EAED,IAAM,EAAa,GAAsB,EAAM,UAAY,EAAM,QAAU,QAAU,YAAc,UAC7F,GAAA,EAAgB,EAAA,SAAA,KAAe,EAAQ,MAAM,OAAQ,GAAU,EAAU,CAAK,IAAM,QAAQ,CAAC,EAC7F,GAAA,EAAmB,EAAA,SAAA,KAAe,EAAQ,MAAM,OAAQ,GAAU,EAAU,CAAK,IAAM,WAAW,CAAC,EAEzG,MAAO,GAAA,IAAI;;;cAGD,EAAa;4BACG,CACpB,EAAY,MAAQ,GACpB,EAAG,UAAU,IAAI,SAAS,CAC5B,EAAE;4BACoB,CACpB,EAAY,MAAQ,GACpB,EAAG,UAAU,OAAO,SAAS,CAC/B,EAAE;uBACe,CACf,EAAY,MAAQ,EACtB,EAAE;wBACgB,CAChB,EAAY,MAAQ,EACtB,EAAE;;;;;;;;;gBASQ,EAAc,MAAM,IAAI,CAAW,EAAE;;;;;;;;;gBASrC,EAAiB,MAAM,IAAI,CAAW,EAAE;;;;KAKxD,EACA,OAAQ,CAAC,EAAA,mBAAoB,EAAA,OAAe,CAC9C,CAAC,EA4BD,IAAM,EAAW,IAAI,QAOrB,SAAgB,EAAmB,EAAmB,SAAS,KAAoB,CACjF,IAAM,EAAW,EAAS,IAAI,CAAI,EAElC,GAAI,EAAU,OAAO,EAErB,IAAM,EAAQ,IAAI,EACZ,EAAqB,IAAI,gBAC3B,EAAW,GACX,EAAa,GACb,EAA2C,KAC3C,EAA2B,KAEzB,MAA8B,CAAC,EAC/B,EAAW,EACX,MAAoC,CACxC,GAAI,CAAC,EAAa,EAAG,OAAO,KAE5B,GAAI,GAAM,YAAa,OAAO,EAc9B,GAZA,EAAO,EAAS,cAA2B,CAAS,EAE/C,IACH,EAAO,SAAS,cAAc,CAAS,EAEnC,GAAe,UAAU,EAAK,aAAa,WAAY,EAAc,QAAQ,EAE7E,GAAe,KAAO,MAAM,EAAK,aAAa,MAAO,OAAO,EAAc,GAAG,CAAC,EAElF,EAAS,YAAY,CAAI,GAGvB,GAAe,KAAO,KAAM,EAAM,OAAO,EAAc,GAAG,MACzD,CACH,IAAM,EAAM,OAAO,EAAK,aAAa,KAAK,CAAC,EAEvC,OAAO,SAAS,CAAG,GAAK,EAAM,GAAG,EAAM,OAAO,CAAG,CACvD,CAMA,MAJA,GAAgB,KAChB,EAAa,GACb,EAAc,EAAM,CAAK,EAElB,CACT,EACM,MAA4B,EAAQ,EAAQ,EAE5C,EAAwB,CAC5B,IAAI,EAAM,CAGR,OAFK,EAAW,EAET,EAAM,IAAI,CAAI,EAFK,EAAK,KAAA,EAAM,EAAA,KAAA,CAAK,CAG5C,EAEA,OAAQ,CACF,EAAW,GAAG,EAAM,MAAM,CAChC,EAEA,UAAU,EAAQ,CACZ,IAMJ,EAAgB,CAAE,GAAG,EAAe,GAAG,CAAO,EAChD,EAEA,QAAQ,EAAI,CACN,EAAW,GAAG,EAAM,QAAQ,CAAE,CACpC,EAEA,IAAI,gBAAiB,CACnB,OAAO,EAAmB,MAC5B,EAEA,SAAU,CACJ,IAEJ,EAAW,GAEX,EAAmB,MAAM,EAEzB,EAAM,QAAQ,EAEV,EAAS,IAAI,CAAI,IAAM,GAAS,EAAS,OAAO,CAAI,EAC1D,EAEA,IAAI,UAAW,CACb,OAAO,CACT,EAEA,MAAM,EAAS,EAAM,CACnB,OAAO,EAAQ,IAAI,CAAE,MAAO,QAAS,GAAG,EAAM,SAAQ,CAAC,CACzD,EAEA,KAAK,EAAS,EAAM,CAClB,OAAO,EAAQ,IAAI,CAAE,MAAO,OAAQ,GAAG,EAAM,SAAQ,CAAC,CACxD,EAEA,MAAM,QAAQ,EAAS,EAAU,CAC/B,IAAM,EAAK,EAAQ,IAAI,CAAE,MAAO,UAAW,YAAa,GAAO,SAAU,EAAG,QAAS,EAAS,OAAQ,CAAC,EAEvG,GAAI,CACF,IAAM,EAAO,MAAM,EASnB,OAPA,EAAQ,OAAO,EAAI,CACjB,MAAO,UACP,YAAa,GACb,SAAU,IACV,QAAS,OAAO,EAAS,SAAY,WAAa,EAAS,QAAQ,CAAI,EAAI,EAAS,OACtF,CAAC,EAEM,CACT,OAAS,EAAK,CAOZ,MANA,EAAQ,OAAO,EAAI,CACjB,MAAO,QACP,YAAa,GACb,SAAU,IACV,QAAS,OAAO,EAAS,OAAU,WAAa,EAAS,MAAM,CAAG,EAAI,EAAS,KACjF,CAAC,EACK,CACR,CACF,EAEA,QAAQ,EAAS,EAAM,CACrB,OAAO,EAAQ,IAAI,CAAE,MAAO,UAAW,GAAG,EAAM,SAAQ,CAAC,CAC3D,EAEA,CAAC,OAAO,UAAW,CACjB,EAAQ,QAAQ,CAClB,EAEA,OAAO,EAAI,EAAS,CACd,EAAW,GAAG,EAAM,OAAO,EAAI,CAAO,CAC5C,EAEA,QAAQ,EAAS,EAAM,CACrB,OAAO,EAAQ,IAAI,CAAE,MAAO,UAAW,GAAG,EAAM,SAAQ,CAAC,CAC3D,CACF,EAIA,OAFA,EAAS,IAAI,EAAM,CAAO,EAEnB,CACT,CAGA,IAAa,EAAsB,EAAmB"}
1
+ {"version":3,"file":"toast.cjs","names":[],"sources":["../src/feedback/toast/toast.ts"],"sourcesContent":["import '../alert/alert';\nimport { createPanGesture, type PanGesture } from '@vielzeug/gesture';\nimport { define, getHost, html, onCleanup, onMounted, prop, ref, useEmit } from '@vielzeug/ore';\nimport { computed, signal, watch } from '@vielzeug/ripple';\nimport { warn } from '../../_dev';\nimport { reducedMotionMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './toast.css?inline';\n\n/** Must match toast.css's default opacity transition duration. */\nconst TOAST_EXIT_MS = 300;\n\nexport type OreToastEvents = {\n add: { id: string };\n dismiss: { id: string };\n};\n\nexport type OreToastProps = {\n max?: number;\n position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';\n};\n\n/** Individual toast notification. */\nexport type ToastItem = {\n actions?: Array<{\n color?: ThemeColor;\n label: string;\n onClick?: () => void;\n variant?: 'solid' | 'flat' | 'bordered';\n }>;\n color?: ThemeColor;\n dismissible?: boolean;\n /** Auto-dismiss delay in ms. Set to 0 for persistent toasts (default: 5000). */\n duration?: number;\n heading?: string;\n /** Show message and actions side-by-side (horizontal layout). */\n horizontal?: boolean;\n /** Auto-generated when omitted. */\n id?: string;\n message: string;\n /** Metadata text (for example, a timestamp) shown in the alert meta slot. */\n meta?: string;\n /** Called after the toast is fully dismissed and removed. */\n onDismiss?: () => void;\n rounded?: RoundedSize | '';\n size?: ComponentSize;\n /**\n * Screen-reader announcement urgency. Error-coloured toasts are assertive by\n * default; all other toasts are polite.\n */\n urgency?: 'polite' | 'assertive';\n variant?: 'solid' | 'flat' | 'bordered';\n};\n\ntype ToastPhase = 'entering' | 'active' | 'exiting';\n\ntype ToastTimer = {\n remaining: number;\n startedAt: number;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n\ntype ToastEntry = Required<Pick<ToastItem, 'dismissible' | 'duration' | 'id'>> &\n Omit<ToastItem, 'dismissible' | 'duration' | 'id'> & {\n exitTimeoutId: ReturnType<typeof setTimeout> | null;\n id: string;\n phase: ToastPhase;\n timer: ToastTimer | null;\n };\n\ntype ToastStoreEvent = {\n id: string;\n type: 'add' | 'dismiss';\n};\n\n/**\n * Owns notification data and every timer. Renderers only subscribe to this\n * store; they never expose imperative mutation methods themselves.\n */\nclass ToastStore {\n readonly #entries = signal<ToastEntry[]>([]);\n readonly #listeners = new Set<(entries: ToastEntry[]) => void>();\n readonly #eventListeners = new Set<(event: ToastStoreEvent) => void>();\n #disposed = false;\n #max = 5;\n\n add(item: ToastItem): string {\n if (this.#disposed) return item.id ?? crypto.randomUUID();\n\n const id = item.id ?? crypto.randomUUID();\n const active = this.#entries.value.filter((entry) => entry.phase !== 'exiting');\n const overflow = active.length - (this.#max - 1);\n\n if (overflow > 0) {\n for (const entry of active.slice(0, overflow)) this.dismiss(entry.id);\n }\n\n const entry: ToastEntry = {\n dismissible: true,\n duration: 5000,\n ...item,\n exitTimeoutId: null,\n id,\n phase: 'entering',\n timer: null,\n };\n\n this.#setEntries([...this.#entries.value, entry]);\n this.#emit({ id, type: 'add' });\n\n requestAnimationFrame(() => {\n if (this.#entry(id)?.phase === 'entering') this.#update(id, { phase: 'active' });\n });\n\n if (entry.duration > 0) this.#scheduleTimer(id, entry.duration);\n\n return id;\n }\n\n clear(): void {\n for (const entry of this.#entries.value) {\n if (entry.phase !== 'exiting') this.dismiss(entry.id);\n }\n }\n\n dispose(): void {\n if (this.#disposed) return;\n\n this.#disposed = true;\n\n for (const entry of this.#entries.value) {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n }\n\n this.#setEntries([]);\n this.#listeners.clear();\n this.#eventListeners.clear();\n }\n\n dismiss(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || entry.phase === 'exiting' || this.#disposed) return;\n\n this.#update(id, { ...this.#clearTimer(entry), phase: 'exiting' });\n this.scheduleFinalization(id, TOAST_EXIT_MS + 50);\n }\n\n finalize(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n this.#setEntries(this.#entries.value.filter((candidate) => candidate.id !== id));\n entry.onDismiss?.();\n this.#emit({ id, type: 'dismiss' });\n }\n\n pauseTimers(): void {\n if (this.#disposed) return;\n\n this.#setEntries(\n this.#entries.value.map((entry) => {\n if (!entry.timer) return entry;\n\n clearTimeout(entry.timer.timeoutId);\n\n return {\n ...entry,\n timer: {\n ...entry.timer,\n remaining: Math.max(0, entry.timer.remaining - (Date.now() - entry.timer.startedAt)),\n },\n };\n }),\n );\n }\n\n resumeTimers(): void {\n if (this.#disposed) return;\n\n for (const entry of this.#entries.value) {\n if (entry.phase === 'active' && entry.timer && entry.timer.remaining > 0) {\n this.#scheduleTimer(entry.id, entry.timer.remaining);\n }\n }\n }\n\n scheduleFinalization(id: string, delay: number): void {\n const entry = this.#entry(id);\n\n if (entry?.phase !== 'exiting' || this.#disposed) return;\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n const exitTimeoutId = setTimeout(() => this.finalize(id), delay);\n\n this.#update(id, { exitTimeoutId });\n }\n\n setMax(max: number | undefined): void {\n if (max != null) this.#max = Math.max(1, max);\n }\n\n subscribe(listener: (entries: ToastEntry[]) => void): () => void {\n listener(this.#entries.value);\n this.#listeners.add(listener);\n\n return () => this.#listeners.delete(listener);\n }\n\n subscribeEvents(listener: (event: ToastStoreEvent) => void): () => void {\n this.#eventListeners.add(listener);\n\n return () => this.#eventListeners.delete(listener);\n }\n\n update(id: string, updates: Partial<ToastItem>): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n const cleared = updates.duration !== undefined ? this.#clearTimer(entry) : entry;\n\n this.#update(id, { ...cleared, ...updates, id });\n\n if (updates.duration !== undefined && updates.duration > 0) this.#scheduleTimer(id, updates.duration);\n }\n\n #clearTimer(entry: ToastEntry): ToastEntry {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n return { ...entry, timer: null };\n }\n\n #emit(event: ToastStoreEvent): void {\n for (const listener of this.#eventListeners) listener(event);\n }\n\n #entry(id: string): ToastEntry | undefined {\n return this.#entries.value.find((entry) => entry.id === id);\n }\n\n #scheduleTimer(id: string, remaining: number): void {\n if (remaining <= 0 || this.#disposed) return;\n\n const timeoutId = setTimeout(() => this.dismiss(id), remaining);\n\n this.#update(id, { timer: { remaining, startedAt: Date.now(), timeoutId } });\n }\n\n #setEntries(entries: ToastEntry[]): void {\n this.#entries.value = entries;\n for (const listener of this.#listeners) listener(entries);\n }\n\n #update(id: string, patch: Partial<ToastEntry>): void {\n this.#setEntries(this.#entries.value.map((entry) => (entry.id === id ? { ...entry, ...patch } : entry)));\n }\n}\n\ntype ToastHostBinding = {\n bind: (store: ToastStore) => void;\n unbind: () => void;\n};\n\nconst hostBindings = new WeakMap<HTMLElement, ToastHostBinding>();\nconst hostStores = new WeakMap<HTMLElement, ToastStore>();\n\nconst bindToastHost = (host: HTMLElement, store: ToastStore): void => {\n hostStores.set(host, store);\n hostBindings.get(host)?.bind(store);\n};\n\n/** Renders the action buttons for a toast entry. */\nfunction renderToastActions(entry: ToastEntry, dismiss: () => void) {\n if (!entry.actions?.length) return '';\n\n return html`\n <div slot=\"actions\" class=\"toast-actions\">\n ${entry.actions.map(\n (action) => html`\n <ore-button\n size=\"sm\"\n color=${action.color || entry.color || 'primary'}\n variant=${action.variant || 'solid'}\n @click=${() => {\n action.onClick?.();\n dismiss();\n }}>\n ${action.label}\n </ore-button>\n `,\n )}\n </div>\n `;\n}\n\nexport const TOAST_TAG = 'ore-toast' as const;\n\n/**\n * Declarative toast host. It subscribes to the service for its scope and\n * renders notifications, but has no imperative mutation API of its own.\n *\n * @element ore-toast\n *\n * @attr {string} position - Stack placement.\n * @attr {number} max - Maximum live notifications for the scoped service.\n */\ndefine<OreToastProps>(TOAST_TAG, {\n props: {\n max: prop.number(5),\n position: prop.oneOf(\n ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'] as const,\n 'bottom-right',\n ),\n },\n setup() {\n const el = getHost() as HTMLElement;\n const emit = useEmit<OreToastEvents>();\n const containerRef = ref<HTMLDivElement>();\n const entries = signal<ToastEntry[]>([]);\n const hoverPaused = signal(false);\n const focusPaused = signal(false);\n const paused = computed(() => hoverPaused.value || focusPaused.value);\n const swipeControls = new Map<string, { element: HTMLElement; gesture: PanGesture }>();\n const exiting = new Map<string, () => void>();\n const swiping = new Set<string>();\n let pendingSyncFrame: number | undefined;\n let store: ToastStore | null = null;\n let unsubscribeEntries = () => {};\n let unsubscribeEvents = () => {};\n\n const getInner = (wrapper: HTMLElement): HTMLElement | null => {\n return wrapper.querySelector<HTMLElement>('.toast-inner');\n };\n\n const clearExitListener = (id: string): void => {\n exiting.get(id)?.();\n exiting.delete(id);\n };\n\n const finalizeSwipe = (id: string): void => {\n swiping.delete(id);\n store?.finalize(id);\n };\n\n const createToastSwipe = (id: string, wrapper: HTMLElement): PanGesture => {\n const isDismissible = (): boolean => entries.value.find((entry) => entry.id === id)?.dismissible ?? true;\n const reset = (): void => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = '';\n inner.style.transform = '';\n inner.style.opacity = '';\n };\n\n return createPanGesture(wrapper, {\n axis: 'x',\n disabled: () => !isDismissible(),\n onEnd: ({ distance, reason }) => {\n if (reason !== 'release' || Math.abs(distance) < 48) {\n reset();\n\n return;\n }\n\n const inner = getInner(wrapper);\n\n if (!inner || !store) return;\n\n swiping.add(id);\n\n store.dismiss(id);\n\n const finish = () => finalizeSwipe(id);\n\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n inner.style.opacity = '0';\n finish();\n\n return;\n }\n\n const direction = distance >= 0 ? 1 : -1;\n\n inner.style.transition = 'transform 0.22s ease-out, opacity 0.22s ease-out';\n void inner.offsetWidth;\n inner.style.transform = `translateX(${direction * 120}%)`;\n inner.style.opacity = '0';\n\n const onTransitionEnd = (transition: TransitionEvent) => {\n if (transition.target !== inner || transition.propertyName !== 'transform') return;\n\n inner.removeEventListener('transitionend', onTransitionEnd);\n finish();\n };\n\n inner.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, 300);\n },\n onMove: ({ distance }) => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = 'none';\n inner.style.transform = `translateX(${distance}px)`;\n inner.style.opacity = String(Math.max(0, 1 - Math.abs(distance) / 200));\n },\n pointerCapture: false,\n shouldStart: (event) =>\n !event\n .composedPath()\n .some((node) => node instanceof Element && node.matches('button, a, input, select, textarea, ore-button')),\n });\n };\n\n const beginExit = (id: string): void => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n requestAnimationFrame(() => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n const inner = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${id}\"] .toast-inner`);\n\n if (!inner) {\n store.scheduleFinalization(id, TOAST_EXIT_MS);\n\n return;\n }\n\n void inner.offsetHeight;\n\n const duration = parseFloat(getComputedStyle(inner).transitionDuration) * 1000;\n const exitMs = Number.isFinite(duration) && duration > 0 ? duration : TOAST_EXIT_MS;\n const onTransitionEnd = (event: TransitionEvent) => {\n const wrapper = (event.target as HTMLElement | null)?.closest?.(`[data-toast-id=\"${id}\"]`);\n\n if (!wrapper) return;\n\n clearExitListener(id);\n store?.finalize(id);\n };\n const remove = () => containerRef.value?.removeEventListener('transitionend', onTransitionEnd);\n\n exiting.set(id, remove);\n containerRef.value?.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, exitMs + 50);\n });\n };\n\n const syncControls = (): void => {\n const currentIds = new Set(entries.value.map((entry) => entry.id));\n\n for (const [id, control] of swipeControls) {\n if (!currentIds.has(id)) {\n control.gesture.dispose();\n\n swipeControls.delete(id);\n clearExitListener(id);\n swiping.delete(id);\n }\n }\n\n for (const entry of entries.value) {\n const wrapper = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${entry.id}\"]`);\n const control = swipeControls.get(entry.id);\n\n if (wrapper && control?.element !== wrapper) {\n control?.gesture.dispose();\n swipeControls.set(entry.id, { element: wrapper, gesture: createToastSwipe(entry.id, wrapper) });\n }\n\n if (entry.phase === 'exiting') beginExit(entry.id);\n }\n };\n\n const scheduleSyncControls = (): void => {\n syncControls();\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n pendingSyncFrame = requestAnimationFrame(() => {\n pendingSyncFrame = undefined;\n syncControls();\n });\n };\n\n watch(entries, scheduleSyncControls);\n watch(paused, (isPaused) => {\n if (isPaused) store?.pauseTimers();\n else store?.resumeTimers();\n });\n\n const bind = (nextStore: ToastStore): void => {\n if (store === nextStore) return;\n\n unsubscribeEntries();\n\n unsubscribeEvents();\n store = nextStore;\n unsubscribeEntries = store.subscribe((nextEntries) => {\n entries.value = nextEntries;\n });\n unsubscribeEvents = store.subscribeEvents((event) => emit(event.type, { id: event.id }));\n\n if (paused.value) store.pauseTimers();\n };\n\n const renderEntry = (entry: ToastEntry) => {\n const dismiss = () => store?.dismiss(entry.id);\n\n return html`\n <div\n class=\"toast-wrapper\"\n data-toast-id=${entry.id}\n part=\"toast-wrapper\">\n <div class=\"${() => `toast-inner${entry.phase !== 'active' ? ` ${entry.phase}` : ''}`}\" part=\"toast-inner\">\n <ore-alert\n color=${entry.color || (entry.urgency === 'assertive' ? 'error' : 'primary')}\n variant=${entry.variant || 'solid'}\n size=${entry.size || 'md'}\n rounded=${entry.rounded || 'md'}\n ?horizontal=${entry.horizontal}\n heading=${entry.heading || ''}\n ?dismissible=${entry.dismissible}\n @dismiss=${dismiss}>\n ${\n entry.meta\n ? html`\n <span slot=\"meta\">${entry.meta}</span>\n `\n : ''\n }\n ${entry.message} ${renderToastActions(entry, dismiss)}\n </ore-alert>\n </div>\n </div>\n `;\n };\n\n onMounted(() => {\n hostBindings.set(el, {\n bind,\n unbind() {\n unsubscribeEntries();\n unsubscribeEvents();\n store = null;\n entries.value = [];\n },\n });\n\n const boundStore = hostStores.get(el);\n\n if (boundStore) bind(boundStore);\n });\n\n onCleanup(() => {\n hostBindings.get(el)?.unbind();\n\n hostBindings.delete(el);\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n for (const control of swipeControls.values()) control.gesture.dispose();\n swipeControls.clear();\n for (const id of exiting.keys()) clearExitListener(id);\n });\n\n const urgencyOf = (entry: ToastEntry) => entry.urgency ?? (entry.color === 'error' ? 'assertive' : 'polite');\n const politeEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'polite'));\n const assertiveEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'assertive'));\n\n return html`\n <div\n class=\"toast-container\"\n ref=${containerRef}\n @pointerenter=${() => {\n hoverPaused.value = true;\n el.classList.add('hovered');\n }}\n @pointerleave=${() => {\n hoverPaused.value = false;\n el.classList.remove('hovered');\n }}\n @focusin=${() => {\n focusPaused.value = true;\n }}\n @focusout=${() => {\n focusPaused.value = false;\n }}\n part=\"container\">\n <div\n role=\"region\"\n aria-live=\"polite\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Notifications\"\n class=\"toast-live-region\">\n ${() => politeEntries.value.map(renderEntry)}\n </div>\n <div\n role=\"region\"\n aria-live=\"assertive\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Critical notifications\"\n class=\"toast-live-region\">\n ${() => assertiveEntries.value.map(renderEntry)}\n </div>\n <slot></slot>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n\nexport type ToastServiceConfig = OreToastProps;\n\nexport interface ToastService {\n add(item: ToastItem): string;\n clear(): void;\n configure(config: ToastServiceConfig): void;\n dismiss(id: string): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n error(message: string, opts?: Partial<ToastItem>): string;\n info(message: string, opts?: Partial<ToastItem>): string;\n promise<T>(\n promise: Promise<T>,\n messages: {\n error: string | ((err: unknown) => string);\n loading: string;\n success: string | ((data: T) => string);\n },\n ): Promise<T>;\n success(message: string, opts?: Partial<ToastItem>): string;\n update(id: string, updates: Partial<ToastItem>): void;\n warning(message: string, opts?: Partial<ToastItem>): string;\n [Symbol.dispose](): void;\n}\n\nconst services = new WeakMap<ParentNode, ToastService>();\n\n/**\n * Creates a scoped toast service. The service owns its notification store and\n * binds it to the declarative `<ore-toast>` host inside `root`, creating that\n * host lazily when notifications are first requested.\n */\nexport function createToastService(root: ParentNode = document.body): ToastService {\n const existing = services.get(root);\n\n if (existing) return existing;\n\n const store = new ToastStore();\n const disposalController = new AbortController();\n let disposed = false;\n let configured = false;\n let pendingConfig: ToastServiceConfig | null = null;\n let host: HTMLElement | null = null;\n\n const assertActive = (): boolean => !disposed;\n const rootNode = root as Element | Document | ShadowRoot;\n const getHost = (): HTMLElement | null => {\n if (!assertActive()) return null;\n\n if (host?.isConnected) return host;\n\n host = rootNode.querySelector<HTMLElement>(TOAST_TAG);\n\n if (!host) {\n host = document.createElement(TOAST_TAG);\n\n if (pendingConfig?.position) host.setAttribute('position', pendingConfig.position);\n\n if (pendingConfig?.max != null) host.setAttribute('max', String(pendingConfig.max));\n\n rootNode.appendChild(host);\n }\n\n if (pendingConfig?.max != null) store.setMax(pendingConfig.max);\n else {\n const max = Number(host.getAttribute('max'));\n\n if (Number.isFinite(max) && max > 0) store.setMax(max);\n }\n\n pendingConfig = null;\n configured = true;\n bindToastHost(host, store);\n\n return host;\n };\n const ensureHost = (): boolean => Boolean(getHost());\n\n const service: ToastService = {\n add(item) {\n if (!ensureHost()) return item.id ?? crypto.randomUUID();\n\n return store.add(item);\n },\n\n clear() {\n if (ensureHost()) store.clear();\n },\n\n configure(config) {\n if (configured) {\n warn('toast.configure() called after the container was already created; options ignored.');\n\n return;\n }\n\n pendingConfig = { ...pendingConfig, ...config };\n },\n\n dismiss(id) {\n if (ensureHost()) store.dismiss(id);\n },\n\n get disposalSignal() {\n return disposalController.signal;\n },\n\n dispose() {\n if (disposed) return;\n\n disposed = true;\n\n disposalController.abort();\n\n store.dispose();\n\n if (services.get(root) === service) services.delete(root);\n },\n\n get disposed() {\n return disposed;\n },\n\n error(message, opts) {\n return service.add({ color: 'error', ...opts, message });\n },\n\n info(message, opts) {\n return service.add({ color: 'info', ...opts, message });\n },\n\n async promise(promise, messages) {\n const id = service.add({ color: 'primary', dismissible: false, duration: 0, message: messages.loading });\n\n try {\n const data = await promise;\n\n service.update(id, {\n color: 'success',\n dismissible: true,\n duration: 5000,\n message: typeof messages.success === 'function' ? messages.success(data) : messages.success,\n });\n\n return data;\n } catch (err) {\n service.update(id, {\n color: 'error',\n dismissible: true,\n duration: 5000,\n message: typeof messages.error === 'function' ? messages.error(err) : messages.error,\n });\n throw err;\n }\n },\n\n success(message, opts) {\n return service.add({ color: 'success', ...opts, message });\n },\n\n [Symbol.dispose]() {\n service.dispose();\n },\n\n update(id, updates) {\n if (ensureHost()) store.update(id, updates);\n },\n\n warning(message, opts) {\n return service.add({ color: 'warning', ...opts, message });\n },\n };\n\n services.set(root, service);\n\n return service;\n}\n\n/** Singleton service backed by a lazily created host in `document.body`. */\nexport const toast: ToastService = createToastService();\n"],"mappings":"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"}
package/dist/toast.js CHANGED
@@ -4,17 +4,16 @@ import t from "./feedback/toast/toast.css.js";
4
4
  import { define as n, getHost as r, html as i, onCleanup as a, onMounted as o, prop as s, ref as c, useEmit as l } from "@vielzeug/ore";
5
5
  import { computed as u, signal as d, watch as f } from "@vielzeug/ripple";
6
6
  import { createPanGesture as p } from "@vielzeug/gesture";
7
- import { uuid as m } from "@vielzeug/arsenal/random";
8
7
  //#region src/feedback/toast/toast.ts
9
- var h = 300, g = class {
8
+ var m = 300, h = class {
10
9
  #e = d([]);
11
10
  #t = /* @__PURE__ */ new Set();
12
11
  #n = /* @__PURE__ */ new Set();
13
12
  #r = !1;
14
13
  #i = 5;
15
14
  add(e) {
16
- if (this.#r) return e.id ?? m();
17
- let t = e.id ?? m(), n = this.#e.value.filter((e) => e.phase !== "exiting"), r = n.length - (this.#i - 1);
15
+ if (this.#r) return e.id ?? crypto.randomUUID();
16
+ let t = e.id ?? crypto.randomUUID(), n = this.#e.value.filter((e) => e.phase !== "exiting"), r = n.length - (this.#i - 1);
18
17
  if (r > 0) for (let e of n.slice(0, r)) this.dismiss(e.id);
19
18
  let i = {
20
19
  dismissible: !0,
@@ -125,10 +124,10 @@ var h = 300, g = class {
125
124
  ...t
126
125
  } : n));
127
126
  }
128
- }, _ = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new WeakMap(), y = (e, t) => {
129
- v.set(e, t), _.get(e)?.bind(t);
127
+ }, g = /* @__PURE__ */ new WeakMap(), _ = /* @__PURE__ */ new WeakMap(), v = (e, t) => {
128
+ _.set(e, t), g.get(e)?.bind(t);
130
129
  };
131
- function b(e, t) {
130
+ function y(e, t) {
132
131
  return e.actions?.length ? i`
133
132
  <div slot="actions" class="toast-actions">
134
133
  ${e.actions.map((n) => i`
@@ -145,8 +144,8 @@ function b(e, t) {
145
144
  </div>
146
145
  ` : "";
147
146
  }
148
- var x = "ore-toast";
149
- n(x, {
147
+ var b = "ore-toast";
148
+ n(b, {
150
149
  props: {
151
150
  max: s.number(5),
152
151
  position: s.oneOf([
@@ -159,7 +158,7 @@ n(x, {
159
158
  ], "bottom-right")
160
159
  },
161
160
  setup() {
162
- let e = r(), t = l(), n = c(), s = d([]), m = d(!1), g = d(!1), y = u(() => m.value || g.value), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Set(), w, T = null, E = () => {}, D = () => {}, O = (e) => e.querySelector(".toast-inner"), k = (e) => {
161
+ let e = r(), t = l(), n = c(), s = d([]), h = d(!1), v = d(!1), b = u(() => h.value || v.value), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Set(), w, T = null, E = () => {}, D = () => {}, O = (e) => e.querySelector(".toast-inner"), k = (e) => {
163
162
  S.get(e)?.(), S.delete(e);
164
163
  }, A = (e) => {
165
164
  C.delete(e), T?.finalize(e);
@@ -203,11 +202,11 @@ n(x, {
203
202
  if (!T || S.has(e) || C.has(e)) return;
204
203
  let t = n.value?.querySelector(`[data-toast-id="${e}"] .toast-inner`);
205
204
  if (!t) {
206
- T.scheduleFinalization(e, h);
205
+ T.scheduleFinalization(e, m);
207
206
  return;
208
207
  }
209
208
  t.offsetHeight;
210
- let r = parseFloat(getComputedStyle(t).transitionDuration) * 1e3, i = Number.isFinite(r) && r > 0 ? r : h, a = (t) => {
209
+ let r = parseFloat(getComputedStyle(t).transitionDuration) * 1e3, i = Number.isFinite(r) && r > 0 ? r : m, a = (t) => {
211
210
  t.target?.closest?.(`[data-toast-id="${e}"]`) && (k(e), T?.finalize(e));
212
211
  };
213
212
  S.set(e, () => n.value?.removeEventListener("transitionend", a)), n.value?.addEventListener("transitionend", a), T.scheduleFinalization(e, i + 50);
@@ -227,13 +226,13 @@ n(x, {
227
226
  N(), w !== void 0 && cancelAnimationFrame(w), w = requestAnimationFrame(() => {
228
227
  w = void 0, N();
229
228
  });
230
- }), f(y, (e) => {
229
+ }), f(b, (e) => {
231
230
  e ? T?.pauseTimers() : T?.resumeTimers();
232
231
  });
233
232
  let P = (e) => {
234
233
  T !== e && (E(), D(), T = e, E = T.subscribe((e) => {
235
234
  s.value = e;
236
- }), D = T.subscribeEvents((e) => t(e.type, { id: e.id })), y.value && T.pauseTimers());
235
+ }), D = T.subscribeEvents((e) => t(e.type, { id: e.id })), b.value && T.pauseTimers());
237
236
  }, F = (e) => {
238
237
  let t = () => T?.dismiss(e.id);
239
238
  return i`
@@ -254,23 +253,23 @@ n(x, {
254
253
  ${e.meta ? i`
255
254
  <span slot="meta">${e.meta}</span>
256
255
  ` : ""}
257
- ${e.message} ${b(e, t)}
256
+ ${e.message} ${y(e, t)}
258
257
  </ore-alert>
259
258
  </div>
260
259
  </div>
261
260
  `;
262
261
  };
263
262
  o(() => {
264
- _.set(e, {
263
+ g.set(e, {
265
264
  bind: P,
266
265
  unbind() {
267
266
  E(), D(), T = null, s.value = [];
268
267
  }
269
268
  });
270
- let t = v.get(e);
269
+ let t = _.get(e);
271
270
  t && P(t);
272
271
  }), a(() => {
273
- _.get(e)?.unbind(), _.delete(e), w !== void 0 && cancelAnimationFrame(w);
272
+ g.get(e)?.unbind(), g.delete(e), w !== void 0 && cancelAnimationFrame(w);
274
273
  for (let e of x.values()) e.gesture.dispose();
275
274
  x.clear();
276
275
  for (let e of S.keys()) k(e);
@@ -281,16 +280,16 @@ n(x, {
281
280
  class="toast-container"
282
281
  ref=${n}
283
282
  @pointerenter=${() => {
284
- m.value = !0, e.classList.add("hovered");
283
+ h.value = !0, e.classList.add("hovered");
285
284
  }}
286
285
  @pointerleave=${() => {
287
- m.value = !1, e.classList.remove("hovered");
286
+ h.value = !1, e.classList.remove("hovered");
288
287
  }}
289
288
  @focusin=${() => {
290
- g.value = !0;
289
+ v.value = !0;
291
290
  }}
292
291
  @focusout=${() => {
293
- g.value = !1;
292
+ v.value = !1;
294
293
  }}
295
294
  part="container">
296
295
  <div
@@ -317,22 +316,22 @@ n(x, {
317
316
  },
318
317
  styles: [e, t]
319
318
  });
320
- var S = /* @__PURE__ */ new WeakMap();
321
- function C(e = document.body) {
322
- let t = S.get(e);
319
+ var x = /* @__PURE__ */ new WeakMap();
320
+ function S(e = document.body) {
321
+ let t = x.get(e);
323
322
  if (t) return t;
324
- let n = new g(), r = new AbortController(), i = !1, a = !1, o = null, s = null, c = () => !i, l = e, u = () => {
323
+ let n = new h(), r = new AbortController(), i = !1, a = !1, o = null, s = null, c = () => !i, l = e, u = () => {
325
324
  if (!c()) return null;
326
325
  if (s?.isConnected) return s;
327
- if (s = l.querySelector(x), s || (s = document.createElement(x), o?.position && s.setAttribute("position", o.position), o?.max != null && s.setAttribute("max", String(o.max)), l.appendChild(s)), o?.max != null) n.setMax(o.max);
326
+ if (s = l.querySelector(b), s || (s = document.createElement(b), o?.position && s.setAttribute("position", o.position), o?.max != null && s.setAttribute("max", String(o.max)), l.appendChild(s)), o?.max != null) n.setMax(o.max);
328
327
  else {
329
328
  let e = Number(s.getAttribute("max"));
330
329
  Number.isFinite(e) && e > 0 && n.setMax(e);
331
330
  }
332
- return o = null, a = !0, y(s, n), s;
331
+ return o = null, a = !0, v(s, n), s;
333
332
  }, d = () => !!u(), f = {
334
333
  add(e) {
335
- return d() ? n.add(e) : e.id ?? m();
334
+ return d() ? n.add(e) : e.id ?? crypto.randomUUID();
336
335
  },
337
336
  clear() {
338
337
  d() && n.clear();
@@ -350,7 +349,7 @@ function C(e = document.body) {
350
349
  return r.signal;
351
350
  },
352
351
  dispose() {
353
- i || (i = !0, r.abort(), n.dispose(), S.get(e) === f && S.delete(e));
352
+ i || (i = !0, r.abort(), n.dispose(), x.get(e) === f && x.delete(e));
354
353
  },
355
354
  get disposed() {
356
355
  return i;
@@ -414,10 +413,10 @@ function C(e = document.body) {
414
413
  });
415
414
  }
416
415
  };
417
- return S.set(e, f), f;
416
+ return x.set(e, f), f;
418
417
  }
419
- var w = C();
418
+ var C = S();
420
419
  //#endregion
421
- export { x as TOAST_TAG, C as createToastService, w as toast };
420
+ export { b as TOAST_TAG, S as createToastService, C as toast };
422
421
 
423
422
  //# sourceMappingURL=toast.js.map
package/dist/toast.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"toast.js","names":["#entries","#listeners","#eventListeners","#disposed","#max","#setEntries","#emit","#entry","#update","#scheduleTimer","#clearTimer"],"sources":["../src/feedback/toast/toast.ts"],"sourcesContent":["import '../alert/alert';\nimport { uuid } from '@vielzeug/arsenal/random';\nimport { createPanGesture, type PanGesture } from '@vielzeug/gesture';\nimport { define, getHost, html, onCleanup, onMounted, prop, ref, useEmit } from '@vielzeug/ore';\nimport { computed, signal, watch } from '@vielzeug/ripple';\nimport { warn } from '../../_dev';\nimport { reducedMotionMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './toast.css?inline';\n\n/** Must match toast.css's default opacity transition duration. */\nconst TOAST_EXIT_MS = 300;\n\nexport type OreToastEvents = {\n add: { id: string };\n dismiss: { id: string };\n};\n\nexport type OreToastProps = {\n max?: number;\n position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';\n};\n\n/** Individual toast notification. */\nexport type ToastItem = {\n actions?: Array<{\n color?: ThemeColor;\n label: string;\n onClick?: () => void;\n variant?: 'solid' | 'flat' | 'bordered';\n }>;\n color?: ThemeColor;\n dismissible?: boolean;\n /** Auto-dismiss delay in ms. Set to 0 for persistent toasts (default: 5000). */\n duration?: number;\n heading?: string;\n /** Show message and actions side-by-side (horizontal layout). */\n horizontal?: boolean;\n /** Auto-generated when omitted. */\n id?: string;\n message: string;\n /** Metadata text (for example, a timestamp) shown in the alert meta slot. */\n meta?: string;\n /** Called after the toast is fully dismissed and removed. */\n onDismiss?: () => void;\n rounded?: RoundedSize | '';\n size?: ComponentSize;\n /**\n * Screen-reader announcement urgency. Error-coloured toasts are assertive by\n * default; all other toasts are polite.\n */\n urgency?: 'polite' | 'assertive';\n variant?: 'solid' | 'flat' | 'bordered';\n};\n\ntype ToastPhase = 'entering' | 'active' | 'exiting';\n\ntype ToastTimer = {\n remaining: number;\n startedAt: number;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n\ntype ToastEntry = Required<Pick<ToastItem, 'dismissible' | 'duration' | 'id'>> &\n Omit<ToastItem, 'dismissible' | 'duration' | 'id'> & {\n exitTimeoutId: ReturnType<typeof setTimeout> | null;\n id: string;\n phase: ToastPhase;\n timer: ToastTimer | null;\n };\n\ntype ToastStoreEvent = {\n id: string;\n type: 'add' | 'dismiss';\n};\n\n/**\n * Owns notification data and every timer. Renderers only subscribe to this\n * store; they never expose imperative mutation methods themselves.\n */\nclass ToastStore {\n readonly #entries = signal<ToastEntry[]>([]);\n readonly #listeners = new Set<(entries: ToastEntry[]) => void>();\n readonly #eventListeners = new Set<(event: ToastStoreEvent) => void>();\n #disposed = false;\n #max = 5;\n\n add(item: ToastItem): string {\n if (this.#disposed) return item.id ?? uuid();\n\n const id = item.id ?? uuid();\n const active = this.#entries.value.filter((entry) => entry.phase !== 'exiting');\n const overflow = active.length - (this.#max - 1);\n\n if (overflow > 0) {\n for (const entry of active.slice(0, overflow)) this.dismiss(entry.id);\n }\n\n const entry: ToastEntry = {\n dismissible: true,\n duration: 5000,\n ...item,\n exitTimeoutId: null,\n id,\n phase: 'entering',\n timer: null,\n };\n\n this.#setEntries([...this.#entries.value, entry]);\n this.#emit({ id, type: 'add' });\n\n requestAnimationFrame(() => {\n if (this.#entry(id)?.phase === 'entering') this.#update(id, { phase: 'active' });\n });\n\n if (entry.duration > 0) this.#scheduleTimer(id, entry.duration);\n\n return id;\n }\n\n clear(): void {\n for (const entry of this.#entries.value) {\n if (entry.phase !== 'exiting') this.dismiss(entry.id);\n }\n }\n\n dispose(): void {\n if (this.#disposed) return;\n\n this.#disposed = true;\n\n for (const entry of this.#entries.value) {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n }\n\n this.#setEntries([]);\n this.#listeners.clear();\n this.#eventListeners.clear();\n }\n\n dismiss(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || entry.phase === 'exiting' || this.#disposed) return;\n\n this.#update(id, { ...this.#clearTimer(entry), phase: 'exiting' });\n this.scheduleFinalization(id, TOAST_EXIT_MS + 50);\n }\n\n finalize(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n this.#setEntries(this.#entries.value.filter((candidate) => candidate.id !== id));\n entry.onDismiss?.();\n this.#emit({ id, type: 'dismiss' });\n }\n\n pauseTimers(): void {\n if (this.#disposed) return;\n\n this.#setEntries(\n this.#entries.value.map((entry) => {\n if (!entry.timer) return entry;\n\n clearTimeout(entry.timer.timeoutId);\n\n return {\n ...entry,\n timer: {\n ...entry.timer,\n remaining: Math.max(0, entry.timer.remaining - (Date.now() - entry.timer.startedAt)),\n },\n };\n }),\n );\n }\n\n resumeTimers(): void {\n if (this.#disposed) return;\n\n for (const entry of this.#entries.value) {\n if (entry.phase === 'active' && entry.timer && entry.timer.remaining > 0) {\n this.#scheduleTimer(entry.id, entry.timer.remaining);\n }\n }\n }\n\n scheduleFinalization(id: string, delay: number): void {\n const entry = this.#entry(id);\n\n if (entry?.phase !== 'exiting' || this.#disposed) return;\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n const exitTimeoutId = setTimeout(() => this.finalize(id), delay);\n\n this.#update(id, { exitTimeoutId });\n }\n\n setMax(max: number | undefined): void {\n if (max != null) this.#max = Math.max(1, max);\n }\n\n subscribe(listener: (entries: ToastEntry[]) => void): () => void {\n listener(this.#entries.value);\n this.#listeners.add(listener);\n\n return () => this.#listeners.delete(listener);\n }\n\n subscribeEvents(listener: (event: ToastStoreEvent) => void): () => void {\n this.#eventListeners.add(listener);\n\n return () => this.#eventListeners.delete(listener);\n }\n\n update(id: string, updates: Partial<ToastItem>): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n const cleared = updates.duration !== undefined ? this.#clearTimer(entry) : entry;\n\n this.#update(id, { ...cleared, ...updates, id });\n\n if (updates.duration !== undefined && updates.duration > 0) this.#scheduleTimer(id, updates.duration);\n }\n\n #clearTimer(entry: ToastEntry): ToastEntry {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n return { ...entry, timer: null };\n }\n\n #emit(event: ToastStoreEvent): void {\n for (const listener of this.#eventListeners) listener(event);\n }\n\n #entry(id: string): ToastEntry | undefined {\n return this.#entries.value.find((entry) => entry.id === id);\n }\n\n #scheduleTimer(id: string, remaining: number): void {\n if (remaining <= 0 || this.#disposed) return;\n\n const timeoutId = setTimeout(() => this.dismiss(id), remaining);\n\n this.#update(id, { timer: { remaining, startedAt: Date.now(), timeoutId } });\n }\n\n #setEntries(entries: ToastEntry[]): void {\n this.#entries.value = entries;\n for (const listener of this.#listeners) listener(entries);\n }\n\n #update(id: string, patch: Partial<ToastEntry>): void {\n this.#setEntries(this.#entries.value.map((entry) => (entry.id === id ? { ...entry, ...patch } : entry)));\n }\n}\n\ntype ToastHostBinding = {\n bind: (store: ToastStore) => void;\n unbind: () => void;\n};\n\nconst hostBindings = new WeakMap<HTMLElement, ToastHostBinding>();\nconst hostStores = new WeakMap<HTMLElement, ToastStore>();\n\nconst bindToastHost = (host: HTMLElement, store: ToastStore): void => {\n hostStores.set(host, store);\n hostBindings.get(host)?.bind(store);\n};\n\n/** Renders the action buttons for a toast entry. */\nfunction renderToastActions(entry: ToastEntry, dismiss: () => void) {\n if (!entry.actions?.length) return '';\n\n return html`\n <div slot=\"actions\" class=\"toast-actions\">\n ${entry.actions.map(\n (action) => html`\n <ore-button\n size=\"sm\"\n color=${action.color || entry.color || 'primary'}\n variant=${action.variant || 'solid'}\n @click=${() => {\n action.onClick?.();\n dismiss();\n }}>\n ${action.label}\n </ore-button>\n `,\n )}\n </div>\n `;\n}\n\nexport const TOAST_TAG = 'ore-toast' as const;\n\n/**\n * Declarative toast host. It subscribes to the service for its scope and\n * renders notifications, but has no imperative mutation API of its own.\n *\n * @element ore-toast\n *\n * @attr {string} position - Stack placement.\n * @attr {number} max - Maximum live notifications for the scoped service.\n */\ndefine<OreToastProps>(TOAST_TAG, {\n props: {\n max: prop.number(5),\n position: prop.oneOf(\n ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'] as const,\n 'bottom-right',\n ),\n },\n setup() {\n const el = getHost() as HTMLElement;\n const emit = useEmit<OreToastEvents>();\n const containerRef = ref<HTMLDivElement>();\n const entries = signal<ToastEntry[]>([]);\n const hoverPaused = signal(false);\n const focusPaused = signal(false);\n const paused = computed(() => hoverPaused.value || focusPaused.value);\n const swipeControls = new Map<string, { element: HTMLElement; gesture: PanGesture }>();\n const exiting = new Map<string, () => void>();\n const swiping = new Set<string>();\n let pendingSyncFrame: number | undefined;\n let store: ToastStore | null = null;\n let unsubscribeEntries = () => {};\n let unsubscribeEvents = () => {};\n\n const getInner = (wrapper: HTMLElement): HTMLElement | null => {\n return wrapper.querySelector<HTMLElement>('.toast-inner');\n };\n\n const clearExitListener = (id: string): void => {\n exiting.get(id)?.();\n exiting.delete(id);\n };\n\n const finalizeSwipe = (id: string): void => {\n swiping.delete(id);\n store?.finalize(id);\n };\n\n const createToastSwipe = (id: string, wrapper: HTMLElement): PanGesture => {\n const isDismissible = (): boolean => entries.value.find((entry) => entry.id === id)?.dismissible ?? true;\n const reset = (): void => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = '';\n inner.style.transform = '';\n inner.style.opacity = '';\n };\n\n return createPanGesture(wrapper, {\n axis: 'x',\n disabled: () => !isDismissible(),\n onEnd: ({ distance, reason }) => {\n if (reason !== 'release' || Math.abs(distance) < 48) {\n reset();\n\n return;\n }\n\n const inner = getInner(wrapper);\n\n if (!inner || !store) return;\n\n swiping.add(id);\n\n store.dismiss(id);\n\n const finish = () => finalizeSwipe(id);\n\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n inner.style.opacity = '0';\n finish();\n\n return;\n }\n\n const direction = distance >= 0 ? 1 : -1;\n\n inner.style.transition = 'transform 0.22s ease-out, opacity 0.22s ease-out';\n void inner.offsetWidth;\n inner.style.transform = `translateX(${direction * 120}%)`;\n inner.style.opacity = '0';\n\n const onTransitionEnd = (transition: TransitionEvent) => {\n if (transition.target !== inner || transition.propertyName !== 'transform') return;\n\n inner.removeEventListener('transitionend', onTransitionEnd);\n finish();\n };\n\n inner.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, 300);\n },\n onMove: ({ distance }) => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = 'none';\n inner.style.transform = `translateX(${distance}px)`;\n inner.style.opacity = String(Math.max(0, 1 - Math.abs(distance) / 200));\n },\n pointerCapture: false,\n shouldStart: (event) =>\n !event\n .composedPath()\n .some((node) => node instanceof Element && node.matches('button, a, input, select, textarea, ore-button')),\n });\n };\n\n const beginExit = (id: string): void => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n requestAnimationFrame(() => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n const inner = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${id}\"] .toast-inner`);\n\n if (!inner) {\n store.scheduleFinalization(id, TOAST_EXIT_MS);\n\n return;\n }\n\n void inner.offsetHeight;\n\n const duration = parseFloat(getComputedStyle(inner).transitionDuration) * 1000;\n const exitMs = Number.isFinite(duration) && duration > 0 ? duration : TOAST_EXIT_MS;\n const onTransitionEnd = (event: TransitionEvent) => {\n const wrapper = (event.target as HTMLElement | null)?.closest?.(`[data-toast-id=\"${id}\"]`);\n\n if (!wrapper) return;\n\n clearExitListener(id);\n store?.finalize(id);\n };\n const remove = () => containerRef.value?.removeEventListener('transitionend', onTransitionEnd);\n\n exiting.set(id, remove);\n containerRef.value?.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, exitMs + 50);\n });\n };\n\n const syncControls = (): void => {\n const currentIds = new Set(entries.value.map((entry) => entry.id));\n\n for (const [id, control] of swipeControls) {\n if (!currentIds.has(id)) {\n control.gesture.dispose();\n\n swipeControls.delete(id);\n clearExitListener(id);\n swiping.delete(id);\n }\n }\n\n for (const entry of entries.value) {\n const wrapper = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${entry.id}\"]`);\n const control = swipeControls.get(entry.id);\n\n if (wrapper && control?.element !== wrapper) {\n control?.gesture.dispose();\n swipeControls.set(entry.id, { element: wrapper, gesture: createToastSwipe(entry.id, wrapper) });\n }\n\n if (entry.phase === 'exiting') beginExit(entry.id);\n }\n };\n\n const scheduleSyncControls = (): void => {\n syncControls();\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n pendingSyncFrame = requestAnimationFrame(() => {\n pendingSyncFrame = undefined;\n syncControls();\n });\n };\n\n watch(entries, scheduleSyncControls);\n watch(paused, (isPaused) => {\n if (isPaused) store?.pauseTimers();\n else store?.resumeTimers();\n });\n\n const bind = (nextStore: ToastStore): void => {\n if (store === nextStore) return;\n\n unsubscribeEntries();\n\n unsubscribeEvents();\n store = nextStore;\n unsubscribeEntries = store.subscribe((nextEntries) => {\n entries.value = nextEntries;\n });\n unsubscribeEvents = store.subscribeEvents((event) => emit(event.type, { id: event.id }));\n\n if (paused.value) store.pauseTimers();\n };\n\n const renderEntry = (entry: ToastEntry) => {\n const dismiss = () => store?.dismiss(entry.id);\n\n return html`\n <div\n class=\"toast-wrapper\"\n data-toast-id=${entry.id}\n part=\"toast-wrapper\">\n <div class=\"${() => `toast-inner${entry.phase !== 'active' ? ` ${entry.phase}` : ''}`}\" part=\"toast-inner\">\n <ore-alert\n color=${entry.color || (entry.urgency === 'assertive' ? 'error' : 'primary')}\n variant=${entry.variant || 'solid'}\n size=${entry.size || 'md'}\n rounded=${entry.rounded || 'md'}\n ?horizontal=${entry.horizontal}\n heading=${entry.heading || ''}\n ?dismissible=${entry.dismissible}\n @dismiss=${dismiss}>\n ${\n entry.meta\n ? html`\n <span slot=\"meta\">${entry.meta}</span>\n `\n : ''\n }\n ${entry.message} ${renderToastActions(entry, dismiss)}\n </ore-alert>\n </div>\n </div>\n `;\n };\n\n onMounted(() => {\n hostBindings.set(el, {\n bind,\n unbind() {\n unsubscribeEntries();\n unsubscribeEvents();\n store = null;\n entries.value = [];\n },\n });\n\n const boundStore = hostStores.get(el);\n\n if (boundStore) bind(boundStore);\n });\n\n onCleanup(() => {\n hostBindings.get(el)?.unbind();\n\n hostBindings.delete(el);\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n for (const control of swipeControls.values()) control.gesture.dispose();\n swipeControls.clear();\n for (const id of exiting.keys()) clearExitListener(id);\n });\n\n const urgencyOf = (entry: ToastEntry) => entry.urgency ?? (entry.color === 'error' ? 'assertive' : 'polite');\n const politeEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'polite'));\n const assertiveEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'assertive'));\n\n return html`\n <div\n class=\"toast-container\"\n ref=${containerRef}\n @pointerenter=${() => {\n hoverPaused.value = true;\n el.classList.add('hovered');\n }}\n @pointerleave=${() => {\n hoverPaused.value = false;\n el.classList.remove('hovered');\n }}\n @focusin=${() => {\n focusPaused.value = true;\n }}\n @focusout=${() => {\n focusPaused.value = false;\n }}\n part=\"container\">\n <div\n role=\"region\"\n aria-live=\"polite\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Notifications\"\n class=\"toast-live-region\">\n ${() => politeEntries.value.map(renderEntry)}\n </div>\n <div\n role=\"region\"\n aria-live=\"assertive\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Critical notifications\"\n class=\"toast-live-region\">\n ${() => assertiveEntries.value.map(renderEntry)}\n </div>\n <slot></slot>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n\nexport type ToastServiceConfig = OreToastProps;\n\nexport interface ToastService {\n add(item: ToastItem): string;\n clear(): void;\n configure(config: ToastServiceConfig): void;\n dismiss(id: string): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n error(message: string, opts?: Partial<ToastItem>): string;\n info(message: string, opts?: Partial<ToastItem>): string;\n promise<T>(\n promise: Promise<T>,\n messages: {\n error: string | ((err: unknown) => string);\n loading: string;\n success: string | ((data: T) => string);\n },\n ): Promise<T>;\n success(message: string, opts?: Partial<ToastItem>): string;\n update(id: string, updates: Partial<ToastItem>): void;\n warning(message: string, opts?: Partial<ToastItem>): string;\n [Symbol.dispose](): void;\n}\n\nconst services = new WeakMap<ParentNode, ToastService>();\n\n/**\n * Creates a scoped toast service. The service owns its notification store and\n * binds it to the declarative `<ore-toast>` host inside `root`, creating that\n * host lazily when notifications are first requested.\n */\nexport function createToastService(root: ParentNode = document.body): ToastService {\n const existing = services.get(root);\n\n if (existing) return existing;\n\n const store = new ToastStore();\n const disposalController = new AbortController();\n let disposed = false;\n let configured = false;\n let pendingConfig: ToastServiceConfig | null = null;\n let host: HTMLElement | null = null;\n\n const assertActive = (): boolean => !disposed;\n const rootNode = root as Element | Document | ShadowRoot;\n const getHost = (): HTMLElement | null => {\n if (!assertActive()) return null;\n\n if (host?.isConnected) return host;\n\n host = rootNode.querySelector<HTMLElement>(TOAST_TAG);\n\n if (!host) {\n host = document.createElement(TOAST_TAG);\n\n if (pendingConfig?.position) host.setAttribute('position', pendingConfig.position);\n\n if (pendingConfig?.max != null) host.setAttribute('max', String(pendingConfig.max));\n\n rootNode.appendChild(host);\n }\n\n if (pendingConfig?.max != null) store.setMax(pendingConfig.max);\n else {\n const max = Number(host.getAttribute('max'));\n\n if (Number.isFinite(max) && max > 0) store.setMax(max);\n }\n\n pendingConfig = null;\n configured = true;\n bindToastHost(host, store);\n\n return host;\n };\n const ensureHost = (): boolean => Boolean(getHost());\n\n const service: ToastService = {\n add(item) {\n if (!ensureHost()) return item.id ?? uuid();\n\n return store.add(item);\n },\n\n clear() {\n if (ensureHost()) store.clear();\n },\n\n configure(config) {\n if (configured) {\n warn('toast.configure() called after the container was already created; options ignored.');\n\n return;\n }\n\n pendingConfig = { ...pendingConfig, ...config };\n },\n\n dismiss(id) {\n if (ensureHost()) store.dismiss(id);\n },\n\n get disposalSignal() {\n return disposalController.signal;\n },\n\n dispose() {\n if (disposed) return;\n\n disposed = true;\n\n disposalController.abort();\n\n store.dispose();\n\n if (services.get(root) === service) services.delete(root);\n },\n\n get disposed() {\n return disposed;\n },\n\n error(message, opts) {\n return service.add({ color: 'error', ...opts, message });\n },\n\n info(message, opts) {\n return service.add({ color: 'info', ...opts, message });\n },\n\n async promise(promise, messages) {\n const id = service.add({ color: 'primary', dismissible: false, duration: 0, message: messages.loading });\n\n try {\n const data = await promise;\n\n service.update(id, {\n color: 'success',\n dismissible: true,\n duration: 5000,\n message: typeof messages.success === 'function' ? messages.success(data) : messages.success,\n });\n\n return data;\n } catch (err) {\n service.update(id, {\n color: 'error',\n dismissible: true,\n duration: 5000,\n message: typeof messages.error === 'function' ? messages.error(err) : messages.error,\n });\n throw err;\n }\n },\n\n success(message, opts) {\n return service.add({ color: 'success', ...opts, message });\n },\n\n [Symbol.dispose]() {\n service.dispose();\n },\n\n update(id, updates) {\n if (ensureHost()) store.update(id, updates);\n },\n\n warning(message, opts) {\n return service.add({ color: 'warning', ...opts, message });\n },\n };\n\n services.set(root, service);\n\n return service;\n}\n\n/** Singleton service backed by a lazily created host in `document.body`. */\nexport const toast: ToastService = createToastService();\n"],"mappings":"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"}
1
+ {"version":3,"file":"toast.js","names":[],"sources":["../src/feedback/toast/toast.ts"],"sourcesContent":["import '../alert/alert';\nimport { createPanGesture, type PanGesture } from '@vielzeug/gesture';\nimport { define, getHost, html, onCleanup, onMounted, prop, ref, useEmit } from '@vielzeug/ore';\nimport { computed, signal, watch } from '@vielzeug/ripple';\nimport { warn } from '../../_dev';\nimport { reducedMotionMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './toast.css?inline';\n\n/** Must match toast.css's default opacity transition duration. */\nconst TOAST_EXIT_MS = 300;\n\nexport type OreToastEvents = {\n add: { id: string };\n dismiss: { id: string };\n};\n\nexport type OreToastProps = {\n max?: number;\n position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';\n};\n\n/** Individual toast notification. */\nexport type ToastItem = {\n actions?: Array<{\n color?: ThemeColor;\n label: string;\n onClick?: () => void;\n variant?: 'solid' | 'flat' | 'bordered';\n }>;\n color?: ThemeColor;\n dismissible?: boolean;\n /** Auto-dismiss delay in ms. Set to 0 for persistent toasts (default: 5000). */\n duration?: number;\n heading?: string;\n /** Show message and actions side-by-side (horizontal layout). */\n horizontal?: boolean;\n /** Auto-generated when omitted. */\n id?: string;\n message: string;\n /** Metadata text (for example, a timestamp) shown in the alert meta slot. */\n meta?: string;\n /** Called after the toast is fully dismissed and removed. */\n onDismiss?: () => void;\n rounded?: RoundedSize | '';\n size?: ComponentSize;\n /**\n * Screen-reader announcement urgency. Error-coloured toasts are assertive by\n * default; all other toasts are polite.\n */\n urgency?: 'polite' | 'assertive';\n variant?: 'solid' | 'flat' | 'bordered';\n};\n\ntype ToastPhase = 'entering' | 'active' | 'exiting';\n\ntype ToastTimer = {\n remaining: number;\n startedAt: number;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n\ntype ToastEntry = Required<Pick<ToastItem, 'dismissible' | 'duration' | 'id'>> &\n Omit<ToastItem, 'dismissible' | 'duration' | 'id'> & {\n exitTimeoutId: ReturnType<typeof setTimeout> | null;\n id: string;\n phase: ToastPhase;\n timer: ToastTimer | null;\n };\n\ntype ToastStoreEvent = {\n id: string;\n type: 'add' | 'dismiss';\n};\n\n/**\n * Owns notification data and every timer. Renderers only subscribe to this\n * store; they never expose imperative mutation methods themselves.\n */\nclass ToastStore {\n readonly #entries = signal<ToastEntry[]>([]);\n readonly #listeners = new Set<(entries: ToastEntry[]) => void>();\n readonly #eventListeners = new Set<(event: ToastStoreEvent) => void>();\n #disposed = false;\n #max = 5;\n\n add(item: ToastItem): string {\n if (this.#disposed) return item.id ?? crypto.randomUUID();\n\n const id = item.id ?? crypto.randomUUID();\n const active = this.#entries.value.filter((entry) => entry.phase !== 'exiting');\n const overflow = active.length - (this.#max - 1);\n\n if (overflow > 0) {\n for (const entry of active.slice(0, overflow)) this.dismiss(entry.id);\n }\n\n const entry: ToastEntry = {\n dismissible: true,\n duration: 5000,\n ...item,\n exitTimeoutId: null,\n id,\n phase: 'entering',\n timer: null,\n };\n\n this.#setEntries([...this.#entries.value, entry]);\n this.#emit({ id, type: 'add' });\n\n requestAnimationFrame(() => {\n if (this.#entry(id)?.phase === 'entering') this.#update(id, { phase: 'active' });\n });\n\n if (entry.duration > 0) this.#scheduleTimer(id, entry.duration);\n\n return id;\n }\n\n clear(): void {\n for (const entry of this.#entries.value) {\n if (entry.phase !== 'exiting') this.dismiss(entry.id);\n }\n }\n\n dispose(): void {\n if (this.#disposed) return;\n\n this.#disposed = true;\n\n for (const entry of this.#entries.value) {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n }\n\n this.#setEntries([]);\n this.#listeners.clear();\n this.#eventListeners.clear();\n }\n\n dismiss(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || entry.phase === 'exiting' || this.#disposed) return;\n\n this.#update(id, { ...this.#clearTimer(entry), phase: 'exiting' });\n this.scheduleFinalization(id, TOAST_EXIT_MS + 50);\n }\n\n finalize(id: string): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n this.#setEntries(this.#entries.value.filter((candidate) => candidate.id !== id));\n entry.onDismiss?.();\n this.#emit({ id, type: 'dismiss' });\n }\n\n pauseTimers(): void {\n if (this.#disposed) return;\n\n this.#setEntries(\n this.#entries.value.map((entry) => {\n if (!entry.timer) return entry;\n\n clearTimeout(entry.timer.timeoutId);\n\n return {\n ...entry,\n timer: {\n ...entry.timer,\n remaining: Math.max(0, entry.timer.remaining - (Date.now() - entry.timer.startedAt)),\n },\n };\n }),\n );\n }\n\n resumeTimers(): void {\n if (this.#disposed) return;\n\n for (const entry of this.#entries.value) {\n if (entry.phase === 'active' && entry.timer && entry.timer.remaining > 0) {\n this.#scheduleTimer(entry.id, entry.timer.remaining);\n }\n }\n }\n\n scheduleFinalization(id: string, delay: number): void {\n const entry = this.#entry(id);\n\n if (entry?.phase !== 'exiting' || this.#disposed) return;\n\n if (entry.exitTimeoutId) clearTimeout(entry.exitTimeoutId);\n\n const exitTimeoutId = setTimeout(() => this.finalize(id), delay);\n\n this.#update(id, { exitTimeoutId });\n }\n\n setMax(max: number | undefined): void {\n if (max != null) this.#max = Math.max(1, max);\n }\n\n subscribe(listener: (entries: ToastEntry[]) => void): () => void {\n listener(this.#entries.value);\n this.#listeners.add(listener);\n\n return () => this.#listeners.delete(listener);\n }\n\n subscribeEvents(listener: (event: ToastStoreEvent) => void): () => void {\n this.#eventListeners.add(listener);\n\n return () => this.#eventListeners.delete(listener);\n }\n\n update(id: string, updates: Partial<ToastItem>): void {\n const entry = this.#entry(id);\n\n if (!entry || this.#disposed) return;\n\n const cleared = updates.duration !== undefined ? this.#clearTimer(entry) : entry;\n\n this.#update(id, { ...cleared, ...updates, id });\n\n if (updates.duration !== undefined && updates.duration > 0) this.#scheduleTimer(id, updates.duration);\n }\n\n #clearTimer(entry: ToastEntry): ToastEntry {\n if (entry.timer) clearTimeout(entry.timer.timeoutId);\n\n return { ...entry, timer: null };\n }\n\n #emit(event: ToastStoreEvent): void {\n for (const listener of this.#eventListeners) listener(event);\n }\n\n #entry(id: string): ToastEntry | undefined {\n return this.#entries.value.find((entry) => entry.id === id);\n }\n\n #scheduleTimer(id: string, remaining: number): void {\n if (remaining <= 0 || this.#disposed) return;\n\n const timeoutId = setTimeout(() => this.dismiss(id), remaining);\n\n this.#update(id, { timer: { remaining, startedAt: Date.now(), timeoutId } });\n }\n\n #setEntries(entries: ToastEntry[]): void {\n this.#entries.value = entries;\n for (const listener of this.#listeners) listener(entries);\n }\n\n #update(id: string, patch: Partial<ToastEntry>): void {\n this.#setEntries(this.#entries.value.map((entry) => (entry.id === id ? { ...entry, ...patch } : entry)));\n }\n}\n\ntype ToastHostBinding = {\n bind: (store: ToastStore) => void;\n unbind: () => void;\n};\n\nconst hostBindings = new WeakMap<HTMLElement, ToastHostBinding>();\nconst hostStores = new WeakMap<HTMLElement, ToastStore>();\n\nconst bindToastHost = (host: HTMLElement, store: ToastStore): void => {\n hostStores.set(host, store);\n hostBindings.get(host)?.bind(store);\n};\n\n/** Renders the action buttons for a toast entry. */\nfunction renderToastActions(entry: ToastEntry, dismiss: () => void) {\n if (!entry.actions?.length) return '';\n\n return html`\n <div slot=\"actions\" class=\"toast-actions\">\n ${entry.actions.map(\n (action) => html`\n <ore-button\n size=\"sm\"\n color=${action.color || entry.color || 'primary'}\n variant=${action.variant || 'solid'}\n @click=${() => {\n action.onClick?.();\n dismiss();\n }}>\n ${action.label}\n </ore-button>\n `,\n )}\n </div>\n `;\n}\n\nexport const TOAST_TAG = 'ore-toast' as const;\n\n/**\n * Declarative toast host. It subscribes to the service for its scope and\n * renders notifications, but has no imperative mutation API of its own.\n *\n * @element ore-toast\n *\n * @attr {string} position - Stack placement.\n * @attr {number} max - Maximum live notifications for the scoped service.\n */\ndefine<OreToastProps>(TOAST_TAG, {\n props: {\n max: prop.number(5),\n position: prop.oneOf(\n ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'] as const,\n 'bottom-right',\n ),\n },\n setup() {\n const el = getHost() as HTMLElement;\n const emit = useEmit<OreToastEvents>();\n const containerRef = ref<HTMLDivElement>();\n const entries = signal<ToastEntry[]>([]);\n const hoverPaused = signal(false);\n const focusPaused = signal(false);\n const paused = computed(() => hoverPaused.value || focusPaused.value);\n const swipeControls = new Map<string, { element: HTMLElement; gesture: PanGesture }>();\n const exiting = new Map<string, () => void>();\n const swiping = new Set<string>();\n let pendingSyncFrame: number | undefined;\n let store: ToastStore | null = null;\n let unsubscribeEntries = () => {};\n let unsubscribeEvents = () => {};\n\n const getInner = (wrapper: HTMLElement): HTMLElement | null => {\n return wrapper.querySelector<HTMLElement>('.toast-inner');\n };\n\n const clearExitListener = (id: string): void => {\n exiting.get(id)?.();\n exiting.delete(id);\n };\n\n const finalizeSwipe = (id: string): void => {\n swiping.delete(id);\n store?.finalize(id);\n };\n\n const createToastSwipe = (id: string, wrapper: HTMLElement): PanGesture => {\n const isDismissible = (): boolean => entries.value.find((entry) => entry.id === id)?.dismissible ?? true;\n const reset = (): void => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = '';\n inner.style.transform = '';\n inner.style.opacity = '';\n };\n\n return createPanGesture(wrapper, {\n axis: 'x',\n disabled: () => !isDismissible(),\n onEnd: ({ distance, reason }) => {\n if (reason !== 'release' || Math.abs(distance) < 48) {\n reset();\n\n return;\n }\n\n const inner = getInner(wrapper);\n\n if (!inner || !store) return;\n\n swiping.add(id);\n\n store.dismiss(id);\n\n const finish = () => finalizeSwipe(id);\n\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n inner.style.opacity = '0';\n finish();\n\n return;\n }\n\n const direction = distance >= 0 ? 1 : -1;\n\n inner.style.transition = 'transform 0.22s ease-out, opacity 0.22s ease-out';\n void inner.offsetWidth;\n inner.style.transform = `translateX(${direction * 120}%)`;\n inner.style.opacity = '0';\n\n const onTransitionEnd = (transition: TransitionEvent) => {\n if (transition.target !== inner || transition.propertyName !== 'transform') return;\n\n inner.removeEventListener('transitionend', onTransitionEnd);\n finish();\n };\n\n inner.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, 300);\n },\n onMove: ({ distance }) => {\n const inner = getInner(wrapper);\n\n if (!inner) return;\n\n inner.style.transition = 'none';\n inner.style.transform = `translateX(${distance}px)`;\n inner.style.opacity = String(Math.max(0, 1 - Math.abs(distance) / 200));\n },\n pointerCapture: false,\n shouldStart: (event) =>\n !event\n .composedPath()\n .some((node) => node instanceof Element && node.matches('button, a, input, select, textarea, ore-button')),\n });\n };\n\n const beginExit = (id: string): void => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n requestAnimationFrame(() => {\n if (!store || exiting.has(id) || swiping.has(id)) return;\n\n const inner = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${id}\"] .toast-inner`);\n\n if (!inner) {\n store.scheduleFinalization(id, TOAST_EXIT_MS);\n\n return;\n }\n\n void inner.offsetHeight;\n\n const duration = parseFloat(getComputedStyle(inner).transitionDuration) * 1000;\n const exitMs = Number.isFinite(duration) && duration > 0 ? duration : TOAST_EXIT_MS;\n const onTransitionEnd = (event: TransitionEvent) => {\n const wrapper = (event.target as HTMLElement | null)?.closest?.(`[data-toast-id=\"${id}\"]`);\n\n if (!wrapper) return;\n\n clearExitListener(id);\n store?.finalize(id);\n };\n const remove = () => containerRef.value?.removeEventListener('transitionend', onTransitionEnd);\n\n exiting.set(id, remove);\n containerRef.value?.addEventListener('transitionend', onTransitionEnd);\n store.scheduleFinalization(id, exitMs + 50);\n });\n };\n\n const syncControls = (): void => {\n const currentIds = new Set(entries.value.map((entry) => entry.id));\n\n for (const [id, control] of swipeControls) {\n if (!currentIds.has(id)) {\n control.gesture.dispose();\n\n swipeControls.delete(id);\n clearExitListener(id);\n swiping.delete(id);\n }\n }\n\n for (const entry of entries.value) {\n const wrapper = containerRef.value?.querySelector<HTMLElement>(`[data-toast-id=\"${entry.id}\"]`);\n const control = swipeControls.get(entry.id);\n\n if (wrapper && control?.element !== wrapper) {\n control?.gesture.dispose();\n swipeControls.set(entry.id, { element: wrapper, gesture: createToastSwipe(entry.id, wrapper) });\n }\n\n if (entry.phase === 'exiting') beginExit(entry.id);\n }\n };\n\n const scheduleSyncControls = (): void => {\n syncControls();\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n pendingSyncFrame = requestAnimationFrame(() => {\n pendingSyncFrame = undefined;\n syncControls();\n });\n };\n\n watch(entries, scheduleSyncControls);\n watch(paused, (isPaused) => {\n if (isPaused) store?.pauseTimers();\n else store?.resumeTimers();\n });\n\n const bind = (nextStore: ToastStore): void => {\n if (store === nextStore) return;\n\n unsubscribeEntries();\n\n unsubscribeEvents();\n store = nextStore;\n unsubscribeEntries = store.subscribe((nextEntries) => {\n entries.value = nextEntries;\n });\n unsubscribeEvents = store.subscribeEvents((event) => emit(event.type, { id: event.id }));\n\n if (paused.value) store.pauseTimers();\n };\n\n const renderEntry = (entry: ToastEntry) => {\n const dismiss = () => store?.dismiss(entry.id);\n\n return html`\n <div\n class=\"toast-wrapper\"\n data-toast-id=${entry.id}\n part=\"toast-wrapper\">\n <div class=\"${() => `toast-inner${entry.phase !== 'active' ? ` ${entry.phase}` : ''}`}\" part=\"toast-inner\">\n <ore-alert\n color=${entry.color || (entry.urgency === 'assertive' ? 'error' : 'primary')}\n variant=${entry.variant || 'solid'}\n size=${entry.size || 'md'}\n rounded=${entry.rounded || 'md'}\n ?horizontal=${entry.horizontal}\n heading=${entry.heading || ''}\n ?dismissible=${entry.dismissible}\n @dismiss=${dismiss}>\n ${\n entry.meta\n ? html`\n <span slot=\"meta\">${entry.meta}</span>\n `\n : ''\n }\n ${entry.message} ${renderToastActions(entry, dismiss)}\n </ore-alert>\n </div>\n </div>\n `;\n };\n\n onMounted(() => {\n hostBindings.set(el, {\n bind,\n unbind() {\n unsubscribeEntries();\n unsubscribeEvents();\n store = null;\n entries.value = [];\n },\n });\n\n const boundStore = hostStores.get(el);\n\n if (boundStore) bind(boundStore);\n });\n\n onCleanup(() => {\n hostBindings.get(el)?.unbind();\n\n hostBindings.delete(el);\n\n if (pendingSyncFrame !== undefined) cancelAnimationFrame(pendingSyncFrame);\n\n for (const control of swipeControls.values()) control.gesture.dispose();\n swipeControls.clear();\n for (const id of exiting.keys()) clearExitListener(id);\n });\n\n const urgencyOf = (entry: ToastEntry) => entry.urgency ?? (entry.color === 'error' ? 'assertive' : 'polite');\n const politeEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'polite'));\n const assertiveEntries = computed(() => entries.value.filter((entry) => urgencyOf(entry) === 'assertive'));\n\n return html`\n <div\n class=\"toast-container\"\n ref=${containerRef}\n @pointerenter=${() => {\n hoverPaused.value = true;\n el.classList.add('hovered');\n }}\n @pointerleave=${() => {\n hoverPaused.value = false;\n el.classList.remove('hovered');\n }}\n @focusin=${() => {\n focusPaused.value = true;\n }}\n @focusout=${() => {\n focusPaused.value = false;\n }}\n part=\"container\">\n <div\n role=\"region\"\n aria-live=\"polite\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Notifications\"\n class=\"toast-live-region\">\n ${() => politeEntries.value.map(renderEntry)}\n </div>\n <div\n role=\"region\"\n aria-live=\"assertive\"\n aria-relevant=\"additions removals\"\n aria-atomic=\"false\"\n aria-label=\"Critical notifications\"\n class=\"toast-live-region\">\n ${() => assertiveEntries.value.map(renderEntry)}\n </div>\n <slot></slot>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n\nexport type ToastServiceConfig = OreToastProps;\n\nexport interface ToastService {\n add(item: ToastItem): string;\n clear(): void;\n configure(config: ToastServiceConfig): void;\n dismiss(id: string): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n error(message: string, opts?: Partial<ToastItem>): string;\n info(message: string, opts?: Partial<ToastItem>): string;\n promise<T>(\n promise: Promise<T>,\n messages: {\n error: string | ((err: unknown) => string);\n loading: string;\n success: string | ((data: T) => string);\n },\n ): Promise<T>;\n success(message: string, opts?: Partial<ToastItem>): string;\n update(id: string, updates: Partial<ToastItem>): void;\n warning(message: string, opts?: Partial<ToastItem>): string;\n [Symbol.dispose](): void;\n}\n\nconst services = new WeakMap<ParentNode, ToastService>();\n\n/**\n * Creates a scoped toast service. The service owns its notification store and\n * binds it to the declarative `<ore-toast>` host inside `root`, creating that\n * host lazily when notifications are first requested.\n */\nexport function createToastService(root: ParentNode = document.body): ToastService {\n const existing = services.get(root);\n\n if (existing) return existing;\n\n const store = new ToastStore();\n const disposalController = new AbortController();\n let disposed = false;\n let configured = false;\n let pendingConfig: ToastServiceConfig | null = null;\n let host: HTMLElement | null = null;\n\n const assertActive = (): boolean => !disposed;\n const rootNode = root as Element | Document | ShadowRoot;\n const getHost = (): HTMLElement | null => {\n if (!assertActive()) return null;\n\n if (host?.isConnected) return host;\n\n host = rootNode.querySelector<HTMLElement>(TOAST_TAG);\n\n if (!host) {\n host = document.createElement(TOAST_TAG);\n\n if (pendingConfig?.position) host.setAttribute('position', pendingConfig.position);\n\n if (pendingConfig?.max != null) host.setAttribute('max', String(pendingConfig.max));\n\n rootNode.appendChild(host);\n }\n\n if (pendingConfig?.max != null) store.setMax(pendingConfig.max);\n else {\n const max = Number(host.getAttribute('max'));\n\n if (Number.isFinite(max) && max > 0) store.setMax(max);\n }\n\n pendingConfig = null;\n configured = true;\n bindToastHost(host, store);\n\n return host;\n };\n const ensureHost = (): boolean => Boolean(getHost());\n\n const service: ToastService = {\n add(item) {\n if (!ensureHost()) return item.id ?? crypto.randomUUID();\n\n return store.add(item);\n },\n\n clear() {\n if (ensureHost()) store.clear();\n },\n\n configure(config) {\n if (configured) {\n warn('toast.configure() called after the container was already created; options ignored.');\n\n return;\n }\n\n pendingConfig = { ...pendingConfig, ...config };\n },\n\n dismiss(id) {\n if (ensureHost()) store.dismiss(id);\n },\n\n get disposalSignal() {\n return disposalController.signal;\n },\n\n dispose() {\n if (disposed) return;\n\n disposed = true;\n\n disposalController.abort();\n\n store.dispose();\n\n if (services.get(root) === service) services.delete(root);\n },\n\n get disposed() {\n return disposed;\n },\n\n error(message, opts) {\n return service.add({ color: 'error', ...opts, message });\n },\n\n info(message, opts) {\n return service.add({ color: 'info', ...opts, message });\n },\n\n async promise(promise, messages) {\n const id = service.add({ color: 'primary', dismissible: false, duration: 0, message: messages.loading });\n\n try {\n const data = await promise;\n\n service.update(id, {\n color: 'success',\n dismissible: true,\n duration: 5000,\n message: typeof messages.success === 'function' ? messages.success(data) : messages.success,\n });\n\n return data;\n } catch (err) {\n service.update(id, {\n color: 'error',\n dismissible: true,\n duration: 5000,\n message: typeof messages.error === 'function' ? messages.error(err) : messages.error,\n });\n throw err;\n }\n },\n\n success(message, opts) {\n return service.add({ color: 'success', ...opts, message });\n },\n\n [Symbol.dispose]() {\n service.dispose();\n },\n\n update(id, updates) {\n if (ensureHost()) store.update(id, updates);\n },\n\n warning(message, opts) {\n return service.add({ color: 'warning', ...opts, message });\n },\n };\n\n services.set(root, service);\n\n return service;\n}\n\n/** Singleton service backed by a lazily created host in `document.body`. */\nexport const toast: ToastService = createToastService();\n"],"mappings":"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"}
package/dist/tooltip.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/theme.css.cjs"),t=require("./core/parse.cjs"),n=require("./shared/prop-bundles.cjs"),r=require("./overlay/shared/use-floating-trigger.cjs"),i=require("./overlay/tooltip/tooltip.css.cjs");let a=require("@vielzeug/ore"),o=require("@vielzeug/ripple");var s=4,c=[`hover`,`focus`],l=new Set([`click`,`focus`,`hover`]),u=e=>{if(e==null||e.trim()===``)return 0;let t=Number(e);return Number.isFinite(t)&&t>=0?t:0},d=e=>e==null?void 0:e===``||e===`true`,f=e=>t.parseStringTriggers(e,l,c),p=`ore-tooltip`;(0,a.define)(p,{props:{...n.sizableBundle,...n.disablableBundle,"close-delay":{default:0,parse:u},content:a.prop.string(),"default-open":a.prop.bool(!1),delay:{default:0,parse:u},open:{default:void 0,parse:d},placement:a.prop.oneOf([`top`,`bottom`,`left`,`right`],`top`),trigger:a.prop.string(`hover,focus`),variant:a.prop.string()},setup(e){let t=(0,a.getHost)(),n=(0,a.useEmit)(),i=(0,a.useSlots)(),c=t.shadowRoot,l=(0,o.computed)(()=>!!e.disabled.value),u=(0,o.computed)(()=>e.open.value!==void 0),d=(0,o.signal)(`top`),p=(0,a.createStableId)(`tooltip`),m=(0,o.computed)(()=>f(e.trigger.value)),h=null,g=null,_=null,v=()=>{g&&=(clearTimeout(g),null)},y=()=>{_&&=(clearTimeout(_),null)},b=r.useFloatingTrigger({bindTriggerAria:e=>(0,a.bind)({aria:{describedby:()=>p}},{target:e}),defaultOpen:e[`default-open`],disabled:l,getPanel:()=>h,offset:8,onCleanup:a.onCleanup,onClose:e=>n(`open-change`,{open:!1,reason:e}),onOpen:e=>n(`open-change`,{open:!0,reason:e}),onPlacementChange:e=>{let t=e.split(`-`)[0];d.value=t,t===`left`&&h&&(h.style.left=`${parseFloat(h.style.left)-s}px`)},openProp:e.open,placement:(0,o.computed)(()=>e.placement.value),slot:()=>c?.querySelector(`slot:not([name])`)??null,slotElements:i.elements(),triggers:(0,o.computed)(()=>[])});function x(t=`hover`){if(u.value||l.value||!e.content.value&&!i.has(`content`).value)return;y(),v();let n=Number(e.delay.value)||0;n>0?g=setTimeout(()=>{g=null,b.open(t),b.updatePosition()},n):(b.open(t),b.updatePosition())}function S(){if(u.value)return;v();let t=Number(e[`close-delay`].value)||0;t>0?(y(),_=setTimeout(()=>{_=null,b.close(`trigger`)},t)):b.close(`trigger`)}return(0,a.onMounted)(()=>{let e=c?.querySelector(`slot:not([name])`),t=[],n=(e,n,r)=>{e.addEventListener(n,r),t.push(()=>e.removeEventListener(n,r))},r=()=>{for(let e of t)e();t=[];let r=e?.assignedElements({flatten:!0})[0];if(!r)return;let i=m.value;i.includes(`hover`)&&(n(r,`pointerenter`,()=>x(`hover`)),n(r,`pointerleave`,S)),i.includes(`focus`)&&(n(r,`focusin`,()=>x(`focus`)),n(r,`focusout`,S)),i.includes(`click`)&&n(r,`click`,()=>b.visible.value?S():x(`click`))};e?.addEventListener(`slotchange`,r),r();let i=b.mount();return()=>{e?.removeEventListener(`slotchange`,r);for(let e of t)e();v(),y(),i()}}),a.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/theme.css.cjs"),t=require("./core/parse.cjs"),n=require("./shared/prop-bundles.cjs"),r=require("./overlay/shared/use-floating-trigger.cjs"),i=require("./overlay/tooltip/tooltip.css.cjs");let a=require("@vielzeug/ore"),o=require("@vielzeug/ripple");var s=4,c=[`hover`,`focus`],l=new Set([`click`,`focus`,`hover`]),u=e=>{if(e==null||e.trim()===``)return 0;let t=Number(e);return Number.isFinite(t)&&t>=0?t:0},d=e=>e==null?void 0:e===``||e===`true`,f=e=>t.parseStringTriggers(e,l,c),p=`ore-tooltip`;(0,a.define)(p,{props:{...n.sizableBundle,...n.disablableBundle,"close-delay":{default:0,parse:u},content:a.prop.string(),"default-open":a.prop.bool(!1),delay:{default:0,parse:u},open:{default:void 0,parse:d},placement:a.prop.oneOf([`top`,`bottom`,`left`,`right`],`top`),trigger:a.prop.string(`hover,focus`),variant:a.prop.string()},setup(e){let t=(0,a.getHost)(),n=(0,a.useEmit)(),i=(0,a.useSlots)(),c=t.shadowRoot,l=(0,o.computed)(()=>!!e.disabled.value),u=(0,o.computed)(()=>e.open.value!==void 0),d=(0,o.signal)(`top`),p=(0,a.createId)(`tooltip`),m=(0,o.computed)(()=>f(e.trigger.value)),h=null,g=null,_=null,v=()=>{g&&=(clearTimeout(g),null)},y=()=>{_&&=(clearTimeout(_),null)},b=r.useFloatingTrigger({bindTriggerAria:e=>(0,a.bind)({attr:{"aria-describedby":()=>p}},{target:e}),defaultOpen:e[`default-open`],disabled:l,getPanel:()=>h,offset:8,onCleanup:a.onCleanup,onClose:e=>n(`open-change`,{open:!1,reason:e}),onOpen:e=>n(`open-change`,{open:!0,reason:e}),onPlacementChange:e=>{let t=e.split(`-`)[0];d.value=t,t===`left`&&h&&(h.style.left=`${parseFloat(h.style.left)-s}px`)},openProp:e.open,placement:(0,o.computed)(()=>e.placement.value),slot:()=>c?.querySelector(`slot:not([name])`)??null,slotElements:i.elements(),triggers:(0,o.computed)(()=>[])});function x(t=`hover`){if(u.value||l.value||!e.content.value&&!i.has(`content`).value)return;y(),v();let n=Number(e.delay.value)||0;n>0?g=setTimeout(()=>{g=null,b.open(t),b.updatePosition()},n):(b.open(t),b.updatePosition())}function S(){if(u.value)return;v();let t=Number(e[`close-delay`].value)||0;t>0?(y(),_=setTimeout(()=>{_=null,b.close(`trigger`)},t)):b.close(`trigger`)}return(0,a.onMounted)(()=>{let e=c?.querySelector(`slot:not([name])`),t=[],n=(e,n,r)=>{e.addEventListener(n,r),t.push(()=>e.removeEventListener(n,r))},r=()=>{for(let e of t)e();t=[];let r=e?.assignedElements({flatten:!0})[0];if(!r)return;let i=m.value;i.includes(`hover`)&&(n(r,`pointerenter`,()=>x(`hover`)),n(r,`pointerleave`,S)),i.includes(`focus`)&&(n(r,`focusin`,()=>x(`focus`)),n(r,`focusout`,S)),i.includes(`click`)&&n(r,`click`,()=>b.visible.value?S():x(`click`))};e?.addEventListener(`slotchange`,r),r();let i=b.mount();return()=>{e?.removeEventListener(`slotchange`,r);for(let e of t)e();v(),y(),i()}}),a.html`
2
2
  <slot></slot>
3
3
  <div
4
4
  class="tooltip"