@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.
- package/README.md +5 -18
- package/dist/accordion-item.cjs +1 -1
- package/dist/accordion-item.cjs.map +1 -1
- package/dist/accordion-item.js +1 -1
- package/dist/accordion-item.js.map +1 -1
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.js.map +1 -1
- package/dist/async.cjs +1 -1
- package/dist/async.cjs.map +1 -1
- package/dist/async.js +3 -3
- package/dist/async.js.map +1 -1
- package/dist/box.cjs.map +1 -1
- package/dist/box.js.map +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.cjs.map +1 -1
- package/dist/card.js +3 -3
- package/dist/card.js.map +1 -1
- package/dist/chat-message.cjs +1 -1
- package/dist/chat-message.cjs.map +1 -1
- package/dist/chat-message.js +1 -1
- package/dist/chat-message.js.map +1 -1
- package/dist/checkbox-group.cjs +1 -1
- package/dist/checkbox-group.cjs.map +1 -1
- package/dist/checkbox-group.js +1 -1
- package/dist/checkbox-group.js.map +1 -1
- package/dist/combobox.cjs +10 -8
- package/dist/combobox.cjs.map +1 -1
- package/dist/combobox.js +62 -51
- package/dist/combobox.js.map +1 -1
- package/dist/command-palette.cjs +1 -1
- package/dist/command-palette.cjs.map +1 -1
- package/dist/command-palette.js +6 -2
- package/dist/command-palette.js.map +1 -1
- package/dist/content/card/card.css.cjs +1 -1
- package/dist/content/card/card.css.cjs.map +1 -1
- package/dist/content/card/card.css.js +1 -1
- package/dist/content/card/card.css.js.map +1 -1
- package/dist/content/card/card.d.ts +2 -2
- package/dist/content/card/card.d.ts.map +1 -1
- package/dist/content/index.d.ts +2 -0
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/list/list-item.css.cjs +1 -1
- package/dist/content/list/list-item.css.cjs.map +1 -1
- package/dist/content/list/list-item.css.js +1 -1
- package/dist/content/list/list-item.css.js.map +1 -1
- package/dist/content/list/list-item.d.ts +9 -0
- package/dist/content/list/list-item.d.ts.map +1 -1
- package/dist/content/pagination/pagination.css.cjs +1 -1
- package/dist/content/pagination/pagination.css.cjs.map +1 -1
- package/dist/content/pagination/pagination.css.js +1 -1
- package/dist/content/pagination/pagination.css.js.map +1 -1
- package/dist/content/stats/stats.css.cjs +2 -0
- package/dist/content/stats/stats.css.cjs.map +1 -0
- package/dist/content/stats/stats.css.js +6 -0
- package/dist/content/stats/stats.css.js.map +1 -0
- package/dist/content/stats/stats.d.ts +72 -0
- package/dist/content/stats/stats.d.ts.map +1 -0
- package/dist/core/auto-resize.cjs +1 -1
- package/dist/core/auto-resize.cjs.map +1 -1
- package/dist/core/auto-resize.js +1 -1
- package/dist/core/auto-resize.js.map +1 -1
- package/dist/core/field-base.cjs +1 -1
- package/dist/core/field-base.cjs.map +1 -1
- package/dist/core/field-base.d.ts +1 -1
- package/dist/core/field-base.js +1 -1
- package/dist/core/field-base.js.map +1 -1
- package/dist/core/nav.cjs +1 -1
- package/dist/core/nav.cjs.map +1 -1
- package/dist/core/nav.d.ts +4 -1
- package/dist/core/nav.d.ts.map +1 -1
- package/dist/core/nav.js +41 -28
- package/dist/core/nav.js.map +1 -1
- package/dist/core/option-list.cjs +1 -1
- package/dist/core/option-list.cjs.map +1 -1
- package/dist/core/option-list.d.ts.map +1 -1
- package/dist/core/option-list.js +30 -28
- package/dist/core/option-list.js.map +1 -1
- package/dist/core/slider.cjs +1 -1
- package/dist/core/slider.cjs.map +1 -1
- package/dist/core/slider.js +1 -1
- package/dist/core/slider.js.map +1 -1
- package/dist/core/spinner.cjs +1 -1
- package/dist/core/spinner.cjs.map +1 -1
- package/dist/core/spinner.js +1 -1
- package/dist/core/spinner.js.map +1 -1
- package/dist/custom-elements.json +5471 -4977
- package/dist/datagrid.cjs +219 -199
- package/dist/datagrid.cjs.map +1 -1
- package/dist/datagrid.js +415 -302
- package/dist/datagrid.js.map +1 -1
- package/dist/disclosure/accordion/accordion.css.cjs +1 -1
- package/dist/disclosure/accordion/accordion.css.cjs.map +1 -1
- package/dist/disclosure/accordion/accordion.css.js +1 -1
- package/dist/disclosure/accordion/accordion.css.js.map +1 -1
- package/dist/disclosure/accordion/accordion.d.ts +5 -5
- package/dist/disclosure/accordion/accordion.d.ts.map +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.cjs +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.cjs.map +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.js +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.js.map +1 -1
- package/dist/disclosure/accordion-item/accordion-item.d.ts +3 -3
- package/dist/disclosure/accordion-item/accordion-item.d.ts.map +1 -1
- package/dist/disclosure/tab-item/tab-item.css.cjs +1 -1
- package/dist/disclosure/tab-item/tab-item.css.cjs.map +1 -1
- package/dist/disclosure/tab-item/tab-item.css.js +1 -1
- package/dist/disclosure/tab-item/tab-item.css.js.map +1 -1
- package/dist/disclosure/tab-item/tab-item.d.ts +6 -3
- package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
- package/dist/disclosure/tabs/tabs.css.cjs +1 -1
- package/dist/disclosure/tabs/tabs.css.cjs.map +1 -1
- package/dist/disclosure/tabs/tabs.css.js +1 -1
- package/dist/disclosure/tabs/tabs.css.js.map +1 -1
- package/dist/disclosure/tabs/tabs.d.ts +9 -5
- package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
- package/dist/drawer.cjs +1 -1
- package/dist/drawer.cjs.map +1 -1
- package/dist/drawer.js +1 -1
- package/dist/drawer.js.map +1 -1
- package/dist/feedback/toast/toast.d.ts.map +1 -1
- package/dist/file-input.cjs +1 -1
- package/dist/file-input.cjs.map +1 -1
- package/dist/file-input.js +2 -2
- package/dist/file-input.js.map +1 -1
- package/dist/frameworks/elements.d.ts +4 -85
- package/dist/frameworks/react.d.ts +5 -4
- package/dist/frameworks/vue.d.ts +4 -4
- package/dist/grid.cjs +2 -2
- package/dist/grid.cjs.map +1 -1
- package/dist/grid.js +21 -18
- package/dist/grid.js.map +1 -1
- package/dist/icon.cjs +1 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +1 -1
- package/dist/icon.js.map +1 -1
- package/dist/input.cjs +5 -4
- package/dist/input.cjs.map +1 -1
- package/dist/input.js +14 -8
- package/dist/input.js.map +1 -1
- package/dist/inputs/combobox/combobox-options.cjs +1 -1
- package/dist/inputs/combobox/combobox-options.cjs.map +1 -1
- package/dist/inputs/combobox/combobox-options.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox-options.js +1 -0
- package/dist/inputs/combobox/combobox-options.js.map +1 -1
- package/dist/inputs/combobox/combobox.css.cjs +1 -1
- package/dist/inputs/combobox/combobox.css.cjs.map +1 -1
- package/dist/inputs/combobox/combobox.css.js +1 -1
- package/dist/inputs/combobox/combobox.css.js.map +1 -1
- package/dist/inputs/combobox/combobox.d.ts +13 -1
- package/dist/inputs/combobox/combobox.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox.types.d.ts +7 -0
- package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.cjs +1 -1
- package/dist/inputs/datagrid/datagrid-model.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.d.ts +17 -3
- package/dist/inputs/datagrid/datagrid-model.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.js +93 -70
- package/dist/inputs/datagrid/datagrid-model.js.map +1 -1
- package/dist/inputs/datagrid/datagrid.css.cjs +1 -1
- package/dist/inputs/datagrid/datagrid.css.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid.css.js +1 -1
- package/dist/inputs/datagrid/datagrid.css.js.map +1 -1
- package/dist/inputs/datagrid/datagrid.d.ts +78 -36
- package/dist/inputs/datagrid/datagrid.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs.map +1 -1
- package/dist/inputs/file-input/file-input-upload.js +1 -1
- package/dist/inputs/file-input/file-input-upload.js.map +1 -1
- package/dist/inputs/index.d.ts +3 -4
- package/dist/inputs/index.d.ts.map +1 -1
- package/dist/inputs/input/input.css.cjs +1 -1
- package/dist/inputs/input/input.css.cjs.map +1 -1
- package/dist/inputs/input/input.css.js +1 -1
- package/dist/inputs/input/input.css.js.map +1 -1
- package/dist/inputs/input/input.d.ts +3 -0
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/select/select.css.cjs +1 -1
- package/dist/inputs/select/select.css.cjs.map +1 -1
- package/dist/inputs/select/select.css.js +1 -1
- package/dist/inputs/select/select.css.js.map +1 -1
- package/dist/inputs/select/select.d.ts +5 -0
- package/dist/inputs/select/select.d.ts.map +1 -1
- package/dist/inputs/shared/field-binding.cjs +1 -1
- package/dist/inputs/shared/field-binding.cjs.map +1 -1
- package/dist/inputs/shared/field-binding.js +6 -6
- package/dist/inputs/shared/field-binding.js.map +1 -1
- package/dist/layout/box/box.css.cjs +1 -1
- package/dist/layout/box/box.css.cjs.map +1 -1
- package/dist/layout/box/box.css.js +1 -1
- package/dist/layout/box/box.css.js.map +1 -1
- package/dist/layout/box/box.d.ts +3 -3
- package/dist/layout/box/box.d.ts.map +1 -1
- package/dist/layout/grid/grid.d.ts.map +1 -1
- package/dist/layout/navbar/navbar.css.cjs +1 -1
- package/dist/layout/navbar/navbar.css.cjs.map +1 -1
- package/dist/layout/navbar/navbar.css.js +1 -1
- package/dist/layout/navbar/navbar.css.js.map +1 -1
- package/dist/layout/navbar/navbar.d.ts +3 -1
- package/dist/layout/navbar/navbar.d.ts.map +1 -1
- package/dist/layout/sidebar/sidebar.css.cjs +1 -1
- package/dist/layout/sidebar/sidebar.css.cjs.map +1 -1
- package/dist/layout/sidebar/sidebar.css.js +1 -1
- package/dist/layout/sidebar/sidebar.css.js.map +1 -1
- package/dist/layout/sidebar/sidebar.d.ts +8 -0
- package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
- package/dist/list-item.cjs +6 -5
- package/dist/list-item.cjs.map +1 -1
- package/dist/list-item.js +23 -17
- package/dist/list-item.js.map +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.cjs.map +1 -1
- package/dist/list.js +1 -1
- package/dist/list.js.map +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.js +7 -7
- package/dist/menu.js.map +1 -1
- package/dist/navbar.cjs +2 -2
- package/dist/navbar.cjs.map +1 -1
- package/dist/navbar.js +91 -87
- package/dist/navbar.js.map +1 -1
- package/dist/navigation-menu.cjs +1 -1
- package/dist/navigation-menu.cjs.map +1 -1
- package/dist/navigation-menu.js +2 -2
- package/dist/navigation-menu.js.map +1 -1
- package/dist/number-input.cjs +1 -1
- package/dist/number-input.cjs.map +1 -1
- package/dist/number-input.js +1 -1
- package/dist/number-input.js.map +1 -1
- package/dist/overlay/popover/popover.css.cjs +1 -1
- package/dist/overlay/popover/popover.css.cjs.map +1 -1
- package/dist/overlay/popover/popover.css.js +1 -1
- package/dist/overlay/popover/popover.css.js.map +1 -1
- package/dist/overlay/popover/popover.d.ts +1 -0
- package/dist/overlay/popover/popover.d.ts.map +1 -1
- package/dist/overlay/shared/use-dialog.cjs +1 -1
- package/dist/overlay/shared/use-dialog.cjs.map +1 -1
- package/dist/overlay/shared/use-dialog.js +1 -1
- package/dist/overlay/shared/use-dialog.js.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.cjs +1 -1
- package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.js +1 -1
- package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
- package/dist/overlay/tooltip/tooltip.d.ts.map +1 -1
- package/dist/popover.cjs +1 -1
- package/dist/popover.cjs.map +1 -1
- package/dist/popover.js +6 -6
- package/dist/popover.js.map +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/radio.cjs +1 -1
- package/dist/radio.cjs.map +1 -1
- package/dist/radio.js +15 -13
- package/dist/radio.js.map +1 -1
- package/dist/rating.cjs +1 -1
- package/dist/rating.cjs.map +1 -1
- package/dist/rating.js +2 -2
- package/dist/rating.js.map +1 -1
- package/dist/refine.cjs +373 -324
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +382 -333
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +417 -368
- package/dist/refine.js.map +1 -1
- package/dist/select.cjs +16 -14
- package/dist/select.cjs.map +1 -1
- package/dist/select.js +118 -112
- package/dist/select.js.map +1 -1
- package/dist/shared/types.d.ts +0 -2
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/sidebar.cjs +28 -23
- package/dist/sidebar.cjs.map +1 -1
- package/dist/sidebar.js +143 -108
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.cjs +1 -1
- package/dist/skeleton.cjs.map +1 -1
- package/dist/skeleton.js +11 -9
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.cjs +1 -1
- package/dist/slider.cjs.map +1 -1
- package/dist/slider.js +21 -21
- package/dist/slider.js.map +1 -1
- package/dist/stats.cjs +18 -0
- package/dist/stats.cjs.map +1 -0
- package/dist/stats.js +88 -0
- package/dist/stats.js.map +1 -0
- package/dist/stepper.cjs +1 -1
- package/dist/stepper.cjs.map +1 -1
- package/dist/stepper.js +1 -1
- package/dist/stepper.js.map +1 -1
- package/dist/styles/mixins/animation.css.cjs +2 -0
- package/dist/styles/mixins/animation.css.cjs.map +1 -1
- package/dist/styles/mixins/animation.css.d.ts.map +1 -1
- package/dist/styles/mixins/animation.css.js +2 -0
- package/dist/styles/mixins/animation.css.js.map +1 -1
- package/dist/tab-item.cjs +1 -1
- package/dist/tab-item.cjs.map +1 -1
- package/dist/tab-item.js +3 -2
- package/dist/tab-item.js.map +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.js +3 -1
- package/dist/tabs.js.map +1 -1
- package/dist/toast.cjs +8 -8
- package/dist/toast.cjs.map +1 -1
- package/dist/toast.js +32 -33
- package/dist/toast.js.map +1 -1
- package/dist/tooltip.cjs +1 -1
- package/dist/tooltip.cjs.map +1 -1
- package/dist/tooltip.js +2 -2
- package/dist/tooltip.js.map +1 -1
- package/dist/types/elements.d.ts +207 -0
- package/package.json +70 -62
package/dist/toast.cjs.map
CHANGED
|
@@ -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":"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"}
|
|
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
|
|
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 ??
|
|
17
|
-
let t = e.id ??
|
|
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
|
-
},
|
|
129
|
-
|
|
127
|
+
}, g = /* @__PURE__ */ new WeakMap(), _ = /* @__PURE__ */ new WeakMap(), v = (e, t) => {
|
|
128
|
+
_.set(e, t), g.get(e)?.bind(t);
|
|
130
129
|
};
|
|
131
|
-
function
|
|
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
|
|
149
|
-
n(
|
|
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([]),
|
|
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,
|
|
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 :
|
|
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(
|
|
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 })),
|
|
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} ${
|
|
256
|
+
${e.message} ${y(e, t)}
|
|
258
257
|
</ore-alert>
|
|
259
258
|
</div>
|
|
260
259
|
</div>
|
|
261
260
|
`;
|
|
262
261
|
};
|
|
263
262
|
o(() => {
|
|
264
|
-
|
|
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 =
|
|
269
|
+
let t = _.get(e);
|
|
271
270
|
t && P(t);
|
|
272
271
|
}), a(() => {
|
|
273
|
-
|
|
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
|
-
|
|
283
|
+
h.value = !0, e.classList.add("hovered");
|
|
285
284
|
}}
|
|
286
285
|
@pointerleave=${() => {
|
|
287
|
-
|
|
286
|
+
h.value = !1, e.classList.remove("hovered");
|
|
288
287
|
}}
|
|
289
288
|
@focusin=${() => {
|
|
290
|
-
|
|
289
|
+
v.value = !0;
|
|
291
290
|
}}
|
|
292
291
|
@focusout=${() => {
|
|
293
|
-
|
|
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
|
|
321
|
-
function
|
|
322
|
-
let t =
|
|
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
|
|
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(
|
|
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,
|
|
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 ??
|
|
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(),
|
|
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
|
|
416
|
+
return x.set(e, f), f;
|
|
418
417
|
}
|
|
419
|
-
var
|
|
418
|
+
var C = S();
|
|
420
419
|
//#endregion
|
|
421
|
-
export {
|
|
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.
|
|
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"
|