@ecopages/radiant-ui 0.1.0-beta.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 +70 -0
- package/dist/components/ui/alert/alert.css +27 -0
- package/dist/components/ui/alert/alert.d.ts +4 -0
- package/dist/components/ui/alert/alert.script.d.ts +25 -0
- package/dist/components/ui/alert/index.d.ts +2 -0
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/alert/index.js.map +7 -0
- package/dist/components/ui/breadcrumb/breadcrumb.css +41 -0
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +59 -0
- package/dist/components/ui/breadcrumb/breadcrumb.script.d.ts +40 -0
- package/dist/components/ui/breadcrumb/index.d.ts +2 -0
- package/dist/components/ui/breadcrumb/index.js +2 -0
- package/dist/components/ui/breadcrumb/index.js.map +7 -0
- package/dist/components/ui/button/button.d.ts +37 -0
- package/dist/components/ui/button/index.d.ts +1 -0
- package/dist/components/ui/button/index.js +2 -0
- package/dist/components/ui/button/index.js.map +7 -0
- package/dist/components/ui/carousel/carousel.css +170 -0
- package/dist/components/ui/carousel/carousel.d.ts +39 -0
- package/dist/components/ui/carousel/carousel.script.d.ts +113 -0
- package/dist/components/ui/carousel/index.d.ts +2 -0
- package/dist/components/ui/carousel/index.js +2 -0
- package/dist/components/ui/carousel/index.js.map +7 -0
- package/dist/components/ui/checkbox/checkbox.css +55 -0
- package/dist/components/ui/checkbox/checkbox.d.ts +4 -0
- package/dist/components/ui/checkbox/checkbox.script.d.ts +58 -0
- package/dist/components/ui/checkbox/index.d.ts +2 -0
- package/dist/components/ui/checkbox/index.js +2 -0
- package/dist/components/ui/checkbox/index.js.map +7 -0
- package/dist/components/ui/combobox/combobox.css +65 -0
- package/dist/components/ui/combobox/combobox.d.ts +53 -0
- package/dist/components/ui/combobox/combobox.script.d.ts +89 -0
- package/dist/components/ui/combobox/index.d.ts +2 -0
- package/dist/components/ui/combobox/index.js +2 -0
- package/dist/components/ui/combobox/index.js.map +7 -0
- package/dist/components/ui/dialog/dialog-registry.d.ts +34 -0
- package/dist/components/ui/dialog/dialog-registry.test.d.ts +1 -0
- package/dist/components/ui/dialog/dialog-types.d.ts +55 -0
- package/dist/components/ui/dialog/dialog.css +53 -0
- package/dist/components/ui/dialog/dialog.d.ts +36 -0
- package/dist/components/ui/dialog/dialog.script.d.ts +61 -0
- package/dist/components/ui/dialog/index.d.ts +4 -0
- package/dist/components/ui/dialog/index.js +2 -0
- package/dist/components/ui/dialog/index.js.map +7 -0
- package/dist/components/ui/disclosure/disclosure-group.script.d.ts +31 -0
- package/dist/components/ui/disclosure/disclosure.css +105 -0
- package/dist/components/ui/disclosure/disclosure.d.ts +35 -0
- package/dist/components/ui/disclosure/disclosure.script.d.ts +38 -0
- package/dist/components/ui/disclosure/index.d.ts +3 -0
- package/dist/components/ui/disclosure/index.js +2 -0
- package/dist/components/ui/disclosure/index.js.map +7 -0
- package/dist/components/ui/feed/feed.css +14 -0
- package/dist/components/ui/feed/feed.d.ts +12 -0
- package/dist/components/ui/feed/feed.script.d.ts +22 -0
- package/dist/components/ui/feed/index.d.ts +2 -0
- package/dist/components/ui/feed/index.js +2 -0
- package/dist/components/ui/feed/index.js.map +7 -0
- package/dist/components/ui/field/field-context.d.ts +20 -0
- package/dist/components/ui/field/field-description.d.ts +8 -0
- package/dist/components/ui/field/field-error.d.ts +9 -0
- package/dist/components/ui/field/field-ssr-hydration.test.d.ts +1 -0
- package/dist/components/ui/field/field.css +26 -0
- package/dist/components/ui/field/field.d.ts +4 -0
- package/dist/components/ui/field/field.script.d.ts +68 -0
- package/dist/components/ui/field/index.d.ts +5 -0
- package/dist/components/ui/field/index.js +2 -0
- package/dist/components/ui/field/index.js.map +7 -0
- package/dist/components/ui/form/control-protocol.d.ts +19 -0
- package/dist/components/ui/form/form-context.d.ts +27 -0
- package/dist/components/ui/form/form-field.test.d.ts +3 -0
- package/dist/components/ui/form/form-store.d.ts +53 -0
- package/dist/components/ui/form/form-store.test.d.ts +1 -0
- package/dist/components/ui/form/form.css +12 -0
- package/dist/components/ui/form/form.d.ts +5 -0
- package/dist/components/ui/form/form.script.d.ts +67 -0
- package/dist/components/ui/form/index.d.ts +7 -0
- package/dist/components/ui/form/index.js +2 -0
- package/dist/components/ui/form/index.js.map +7 -0
- package/dist/components/ui/form/resolvers.d.ts +3 -0
- package/dist/components/ui/form/types.d.ts +72 -0
- package/dist/components/ui/grid/grid.css +47 -0
- package/dist/components/ui/grid/grid.d.ts +7 -0
- package/dist/components/ui/grid/grid.script.d.ts +26 -0
- package/dist/components/ui/grid/index.d.ts +2 -0
- package/dist/components/ui/grid/index.js +2 -0
- package/dist/components/ui/grid/index.js.map +7 -0
- package/dist/components/ui/input/index.d.ts +1 -0
- package/dist/components/ui/input/index.js +2 -0
- package/dist/components/ui/input/index.js.map +7 -0
- package/dist/components/ui/input/input.css +32 -0
- package/dist/components/ui/input/input.d.ts +23 -0
- package/dist/components/ui/label/index.d.ts +1 -0
- package/dist/components/ui/label/index.js +2 -0
- package/dist/components/ui/label/index.js.map +7 -0
- package/dist/components/ui/label/label.css +8 -0
- package/dist/components/ui/label/label.d.ts +9 -0
- package/dist/components/ui/listbox/index.d.ts +2 -0
- package/dist/components/ui/listbox/index.js +2 -0
- package/dist/components/ui/listbox/index.js.map +7 -0
- package/dist/components/ui/listbox/listbox.css +23 -0
- package/dist/components/ui/listbox/listbox.d.ts +12 -0
- package/dist/components/ui/listbox/listbox.script.d.ts +40 -0
- package/dist/components/ui/menu-button/index.d.ts +2 -0
- package/dist/components/ui/menu-button/index.js +2 -0
- package/dist/components/ui/menu-button/index.js.map +7 -0
- package/dist/components/ui/menu-button/menu-button.css +43 -0
- package/dist/components/ui/menu-button/menu-button.d.ts +13 -0
- package/dist/components/ui/menu-button/menu-button.script.d.ts +64 -0
- package/dist/components/ui/menubar/index.d.ts +2 -0
- package/dist/components/ui/menubar/index.js +2 -0
- package/dist/components/ui/menubar/index.js.map +7 -0
- package/dist/components/ui/menubar/menubar.css +45 -0
- package/dist/components/ui/menubar/menubar.d.ts +16 -0
- package/dist/components/ui/menubar/menubar.script.d.ts +52 -0
- package/dist/components/ui/meter/index.d.ts +2 -0
- package/dist/components/ui/meter/index.js +2 -0
- package/dist/components/ui/meter/index.js.map +7 -0
- package/dist/components/ui/meter/meter.css +17 -0
- package/dist/components/ui/meter/meter.d.ts +4 -0
- package/dist/components/ui/meter/meter.script.d.ts +33 -0
- package/dist/components/ui/navigation-menu/index.d.ts +2 -0
- package/dist/components/ui/navigation-menu/index.js +2 -0
- package/dist/components/ui/navigation-menu/index.js.map +7 -0
- package/dist/components/ui/navigation-menu/navigation-menu.css +90 -0
- package/dist/components/ui/navigation-menu/navigation-menu.d.ts +28 -0
- package/dist/components/ui/navigation-menu/navigation-menu.script.d.ts +49 -0
- package/dist/components/ui/radio-group/index.d.ts +2 -0
- package/dist/components/ui/radio-group/index.js +2 -0
- package/dist/components/ui/radio-group/index.js.map +7 -0
- package/dist/components/ui/radio-group/radio-group.css +44 -0
- package/dist/components/ui/radio-group/radio-group.d.ts +12 -0
- package/dist/components/ui/radio-group/radio-group.script.d.ts +52 -0
- package/dist/components/ui/sidebar/index.d.ts +3 -0
- package/dist/components/ui/sidebar/index.js +2 -0
- package/dist/components/ui/sidebar/index.js.map +7 -0
- package/dist/components/ui/sidebar/sidebar-trigger.script.d.ts +53 -0
- package/dist/components/ui/sidebar/sidebar.css +362 -0
- package/dist/components/ui/sidebar/sidebar.d.ts +141 -0
- package/dist/components/ui/sidebar/sidebar.script.d.ts +140 -0
- package/dist/components/ui/sidebar/sidebar.test.d.ts +1 -0
- package/dist/components/ui/slider/index.d.ts +2 -0
- package/dist/components/ui/slider/index.js +2 -0
- package/dist/components/ui/slider/index.js.map +7 -0
- package/dist/components/ui/slider/slider.css +51 -0
- package/dist/components/ui/slider/slider.d.ts +7 -0
- package/dist/components/ui/slider/slider.script.d.ts +102 -0
- package/dist/components/ui/spinbutton/index.d.ts +2 -0
- package/dist/components/ui/spinbutton/index.js +2 -0
- package/dist/components/ui/spinbutton/index.js.map +7 -0
- package/dist/components/ui/spinbutton/spinbutton.css +19 -0
- package/dist/components/ui/spinbutton/spinbutton.d.ts +4 -0
- package/dist/components/ui/spinbutton/spinbutton.script.d.ts +64 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +2 -0
- package/dist/components/ui/switch/index.js.map +7 -0
- package/dist/components/ui/switch/switch.css +47 -0
- package/dist/components/ui/switch/switch.d.ts +4 -0
- package/dist/components/ui/switch/switch.script.d.ts +51 -0
- package/dist/components/ui/tabs/index.d.ts +2 -0
- package/dist/components/ui/tabs/index.js +2 -0
- package/dist/components/ui/tabs/index.js.map +7 -0
- package/dist/components/ui/tabs/tabs.css +28 -0
- package/dist/components/ui/tabs/tabs.d.ts +12 -0
- package/dist/components/ui/tabs/tabs.script.d.ts +54 -0
- package/dist/components/ui/textarea/index.d.ts +1 -0
- package/dist/components/ui/textarea/index.js +2 -0
- package/dist/components/ui/textarea/index.js.map +7 -0
- package/dist/components/ui/textarea/textarea.css +33 -0
- package/dist/components/ui/textarea/textarea.d.ts +23 -0
- package/dist/components/ui/toast/index.d.ts +5 -0
- package/dist/components/ui/toast/index.js +2 -0
- package/dist/components/ui/toast/index.js.map +7 -0
- package/dist/components/ui/toast/toast-api.d.ts +29 -0
- package/dist/components/ui/toast/toast-context.d.ts +59 -0
- package/dist/components/ui/toast/toast-state.d.ts +25 -0
- package/dist/components/ui/toast/toast.css +315 -0
- package/dist/components/ui/toast/toast.d.ts +8 -0
- package/dist/components/ui/toast/toast.script.d.ts +91 -0
- package/dist/components/ui/toast/toast.test.d.ts +2 -0
- package/dist/components/ui/toast/toaster.script.d.ts +79 -0
- package/dist/components/ui/toolbar/index.d.ts +2 -0
- package/dist/components/ui/toolbar/index.js +2 -0
- package/dist/components/ui/toolbar/index.js.map +7 -0
- package/dist/components/ui/toolbar/toolbar.css +16 -0
- package/dist/components/ui/toolbar/toolbar.d.ts +4 -0
- package/dist/components/ui/toolbar/toolbar.script.d.ts +30 -0
- package/dist/components/ui/tooltip/index.d.ts +2 -0
- package/dist/components/ui/tooltip/index.js +2 -0
- package/dist/components/ui/tooltip/index.js.map +7 -0
- package/dist/components/ui/tooltip/tooltip.css +25 -0
- package/dist/components/ui/tooltip/tooltip.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.script.d.ts +70 -0
- package/dist/components/ui/tree/index.d.ts +2 -0
- package/dist/components/ui/tree/index.js +2 -0
- package/dist/components/ui/tree/index.js.map +7 -0
- package/dist/components/ui/tree/tree.css +54 -0
- package/dist/components/ui/tree/tree.d.ts +13 -0
- package/dist/components/ui/tree/tree.script.d.ts +45 -0
- package/dist/components/ui/treegrid/index.d.ts +2 -0
- package/dist/components/ui/treegrid/index.js +2 -0
- package/dist/components/ui/treegrid/index.js.map +7 -0
- package/dist/components/ui/treegrid/treegrid.css +77 -0
- package/dist/components/ui/treegrid/treegrid.d.ts +14 -0
- package/dist/components/ui/treegrid/treegrid.script.d.ts +49 -0
- package/dist/components/ui/window-splitter/index.d.ts +2 -0
- package/dist/components/ui/window-splitter/index.js +2 -0
- package/dist/components/ui/window-splitter/index.js.map +7 -0
- package/dist/components/ui/window-splitter/window-splitter.css +35 -0
- package/dist/components/ui/window-splitter/window-splitter.d.ts +8 -0
- package/dist/components/ui/window-splitter/window-splitter.script.d.ts +49 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/lib/focusable-elements.d.ts +2 -0
- package/dist/lib/radiant-view.d.ts +17 -0
- package/dist/lib/roving-tabindex.d.ts +27 -0
- package/dist/styles/components/button.css +115 -0
- package/dist/styles/radiant-ui-core.css +7 -0
- package/dist/styles/radiant-ui.css +10 -0
- package/dist/styles/styles.css +36 -0
- package/dist/styles/tailwind.css +41 -0
- package/dist/styles/themes/aurora.css +19 -0
- package/dist/styles/themes/default-compact-soft.css +19 -0
- package/dist/styles/themes/default.css +2 -0
- package/dist/styles/themes/glacier.css +19 -0
- package/dist/styles/tokens/colors/aurora.css +73 -0
- package/dist/styles/tokens/colors/basalt.css +36 -0
- package/dist/styles/tokens/colors/glacier.css +45 -0
- package/dist/styles/tokens/colors/palettes.css +3 -0
- package/dist/styles/tokens/elevation/default.css +22 -0
- package/dist/styles/tokens/elevation/flat.css +22 -0
- package/dist/styles/tokens/motion/default.css +19 -0
- package/dist/styles/tokens/motion/snappy.css +19 -0
- package/dist/styles/tokens/presets/colors/aurora.css +126 -0
- package/dist/styles/tokens/presets/colors/basalt.css +126 -0
- package/dist/styles/tokens/presets/colors/ember.css +134 -0
- package/dist/styles/tokens/presets/colors/glacier.css +130 -0
- package/dist/styles/tokens/presets/colors/index.css +4 -0
- package/dist/styles/tokens/presets/radius.css +45 -0
- package/dist/styles/tokens/presets/spacing.css +57 -0
- package/dist/styles/tokens/radius/default.css +34 -0
- package/dist/styles/tokens/radius/edgy.css +35 -0
- package/dist/styles/tokens/radius/sharp.css +2 -0
- package/dist/styles/tokens/radius/soft.css +34 -0
- package/dist/styles/tokens/semantic.css +80 -0
- package/dist/styles/tokens/spacing/compact.css +23 -0
- package/dist/styles/tokens/spacing/default.css +23 -0
- package/dist/styles/tokens/spacing/scale-bridge.css +17 -0
- package/dist/styles/tokens/spacing/wide.css +23 -0
- package/dist/styles/tokens/system.css +36 -0
- package/dist/styles/tokens/typography/default.css +37 -0
- package/dist/styles/utilities/sheen.css +7 -0
- package/dist/types.d.ts +14 -0
- package/package.json +371 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/components/ui/toast/toast.script.tsx", "../../../../src/components/ui/toast/toast-context.ts", "../../../../src/components/ui/toast/toast-state.ts", "../../../../src/components/ui/toast/toaster.script.tsx", "../../../../src/lib/radiant-view.ts", "../../../../src/components/ui/toast/toast.tsx", "../../../../src/components/ui/toast/toast-api.ts"],
|
|
4
|
+
"sourcesContent": ["import { RadiantElement, bound, customElement, onEvent, onUpdated, prop, query } from '@ecopages/radiant';\nimport {\n\tDEFAULT_TOAST_POSITION,\n\tTOAST_EXIT_MS,\n\tTOAST_LIFETIME,\n\tTOAST_SWIPE_THRESHOLD,\n\ttype ToastId,\n\ttype ToastPosition,\n\ttype ToastVariant,\n\tsplitToastPosition,\n} from './toast-context';\nimport { toastState } from './toast-state';\n\nexport type RuiToastProps = {\n\t/** JSX list reconciliation key (not reflected to the DOM). */\n\tkey?: string | number;\n\ttoastId?: ToastId;\n\ttitle?: string;\n\tdescription?: string;\n\tvariant?: ToastVariant;\n\tduration?: number;\n\tdismissible?: boolean;\n\tcloseButton?: boolean;\n\tactionLabel?: string;\n\tposition?: ToastPosition;\n\t/** When true, plays the exit animation then removes the toast. */\n\tmarkedDelete?: boolean;\n};\n\ntype RuiToastBindings = {\n\ttitle: string;\n\tdescription: string;\n\tvariant: ToastVariant;\n\tactionLabel: string;\n\tcloseButton: boolean;\n};\n\n/**\n * `<rui-toast>` \u2014 a single transient notification in a toaster stack.\n *\n * Prefer the imperative {@link toast} API with `<rui-toaster>`; this element is\n * rendered by the toaster and is not typically authored by hand.\n *\n * @element rui-toast\n */\n@customElement('rui-toast')\nexport class RuiToast extends RadiantElement<RuiToastBindings> {\n\t@prop({ type: String, reflect: true, defaultValue: '' }) toastId: string;\n\t@prop({ type: String, defaultValue: '' }) title: string;\n\t@prop({ type: String, defaultValue: '' }) description: string;\n\t@prop({ type: String, reflect: true, defaultValue: 'default' }) variant: ToastVariant;\n\t@prop({ type: Number, defaultValue: TOAST_LIFETIME }) duration: number;\n\t@prop({ type: Boolean, defaultValue: true }) dismissible: boolean;\n\t@prop({ type: Boolean, defaultValue: false }) closeButton: boolean;\n\t@prop({ type: String, defaultValue: '' }) actionLabel: string;\n\t@prop({ type: String, defaultValue: DEFAULT_TOAST_POSITION }) position: ToastPosition;\n\t@prop({ type: Boolean, defaultValue: false }) markedDelete: boolean;\n\n\t@query({ ref: 'toast' }) toastTarget: HTMLElement;\n\n\tprivate mounted = false;\n\tprivate removed = false;\n\tprivate swiping = false;\n\tprivate swipeOut = false;\n\tprivate swipeAxis: 'x' | 'y' | null = null;\n\tprivate swipeOutDirection: 'left' | 'right' | 'up' | 'down' | null = null;\n\tprivate held = false;\n\tprivate timerReady = false;\n\tprivate timeoutId: ReturnType<typeof setTimeout> | null = null;\n\tprivate pointerStart: { x: number; y: number } | null = null;\n\tprivate dragStartTime: number | null = null;\n\tprivate exitTimer: ReturnType<typeof setTimeout> | null = null;\n\n\t/**\n\t * Wire pointer listeners, then announce mount after paint so enter CSS can run.\n\t * On reconnect, re-announce without restarting the enter sequence.\n\t */\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback();\n\t\tconst isReconnect = this.mounted;\n\n\t\tthis.addEventListener('pointerdown', this.onPointerDown);\n\t\tthis.addEventListener('pointermove', this.onPointerMove);\n\t\tthis.addEventListener('pointerup', this.onPointerUp);\n\t\tthis.addEventListener('pointercancel', this.onPointerUp);\n\n\t\tif (isReconnect) {\n\t\t\tthis.syncDomState();\n\t\t\tthis.dispatchEvent(new CustomEvent('rui-toast-mounted', { bubbles: true }));\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timerReady = false;\n\t\trequestAnimationFrame(() => {\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (!this.isConnected) return;\n\t\t\t\tthis.mounted = true;\n\t\t\t\tthis.timerReady = true;\n\t\t\t\tthis.syncDomState();\n\t\t\t\tthis.dispatchEvent(new CustomEvent('rui-toast-mounted', { bubbles: true }));\n\t\t\t});\n\t\t});\n\t\tthis.syncDomState();\n\t}\n\n\t/**\n\t * Clear timers on unmount. Only purge shared state when this instance was exiting \u2014\n\t * overflow toasts are intentionally unmounted while still queued.\n\t */\n\toverride disconnectedCallback(): void {\n\t\tthis.clearTimer();\n\t\tif (this.exitTimer) {\n\t\t\tclearTimeout(this.exitTimer);\n\t\t\tthis.exitTimer = null;\n\t\t}\n\t\tconst id = this.resolvedId;\n\t\tif (id !== '' && this.removed) {\n\t\t\ttoastState.remove(id);\n\t\t}\n\t\tthis.held = false;\n\t\tthis.timerReady = false;\n\t\tthis.removeEventListener('pointerdown', this.onPointerDown);\n\t\tthis.removeEventListener('pointermove', this.onPointerMove);\n\t\tthis.removeEventListener('pointerup', this.onPointerUp);\n\t\tthis.removeEventListener('pointercancel', this.onPointerUp);\n\t\tsuper.disconnectedCallback();\n\t}\n\n\t@onUpdated(['title', 'description', 'variant', 'actionLabel', 'closeButton'])\n\tonContentUpdated(): void {\n\t\tthis.requestUpdate();\n\t}\n\n\t@onUpdated('position')\n\tonPositionUpdated(): void {\n\t\tthis.syncDomState();\n\t}\n\n\t/**\n\t * Hold or release auto-dismiss (toaster-controlled on stack hover).\n\t * Leaving hover resets lifetime to a full `duration` (does not resume leftover time).\n\t * A no-op `setPaused(false)` still starts the timer on first paint if it never ran.\n\t */\n\tsetPaused(paused: boolean): void {\n\t\tif (this.held === paused) {\n\t\t\tif (!paused && this.timerReady && this.mounted && !this.removed && !this.timeoutId) {\n\t\t\t\tthis.startTimer();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis.held = paused;\n\t\tif (!this.timerReady || !this.mounted || this.removed) return;\n\t\tif (paused || document.hidden) {\n\t\t\tthis.clearTimer();\n\t\t} else {\n\t\t\tthis.startTimer();\n\t\t}\n\t}\n\n\t@onUpdated('duration')\n\tonDurationUpdated(): void {\n\t\tif (!this.timerReady || !this.mounted || this.removed || this.held) return;\n\t\tthis.startTimer();\n\t}\n\n\t@onUpdated('markedDelete')\n\tonMarkedDeleteUpdated(): void {\n\t\tif (this.markedDelete && !this.removed) {\n\t\t\tthis.beginRemove();\n\t\t}\n\t}\n\n\tprivate get resolvedId(): ToastId {\n\t\tconst raw = this.toastId;\n\t\tif (raw == null || raw === '') return '';\n\t\tconst asNumber = Number(raw);\n\t\treturn Number.isFinite(asNumber) && String(asNumber) === raw ? asNumber : raw;\n\t}\n\n\tprivate clearTimer(): void {\n\t\tif (this.timeoutId) clearTimeout(this.timeoutId);\n\t\tthis.timeoutId = null;\n\t}\n\n\t/** Start a fresh full-duration countdown (never resumes leftover time). */\n\tprivate startTimer(): void {\n\t\tif (this.held || this.removed || document.hidden) return;\n\t\tif (this.duration === Number.POSITIVE_INFINITY || this.variant === 'loading') return;\n\t\tif (this.duration <= 0) {\n\t\t\tthis.beginRemove();\n\t\t\treturn;\n\t\t}\n\t\tthis.clearTimer();\n\t\tthis.timeoutId = setTimeout(() => this.beginRemove(), this.duration);\n\t}\n\n\tprivate beginRemove(): void {\n\t\tif (this.removed) return;\n\t\tthis.removed = true;\n\t\tthis.clearTimer();\n\t\tthis.syncDomState();\n\t\tif (!this.markedDelete) {\n\t\t\ttoastState.dismiss(this.resolvedId);\n\t\t}\n\t\tthis.exitTimer = setTimeout(() => {\n\t\t\tthis.exitTimer = null;\n\t\t\ttoastState.remove(this.resolvedId);\n\t\t}, TOAST_EXIT_MS);\n\t}\n\n\t@bound\n\tprivate onPointerDown(event: PointerEvent): void {\n\t\tif (!this.dismissible || this.variant === 'loading') return;\n\t\tif (event.button !== 0) return;\n\t\tconst target = event.target as HTMLElement | null;\n\t\tif (target?.closest('[data-toast-close], [data-toast-action], button, a')) return;\n\n\t\tthis.dragStartTime = Date.now();\n\t\tthis.pointerStart = { x: event.clientX, y: event.clientY };\n\t\tthis.swipeAxis = null;\n\t\tthis.setPointerCapture(event.pointerId);\n\t}\n\n\t@bound\n\tprivate onPointerMove(event: PointerEvent): void {\n\t\tif (!this.pointerStart) return;\n\t\tconst { y, x } = splitToastPosition(this.position);\n\t\tconst deltaX = event.clientX - this.pointerStart.x;\n\t\tconst deltaY = event.clientY - this.pointerStart.y;\n\n\t\tif (!this.swiping) {\n\t\t\tif (Math.abs(deltaX) < 8 && Math.abs(deltaY) < 8) return;\n\t\t\tthis.swiping = true;\n\t\t\tthis.syncDomState();\n\t\t}\n\n\t\tif (!this.swipeAxis) {\n\t\t\tthis.swipeAxis = Math.abs(deltaX) > Math.abs(deltaY) ? 'x' : 'y';\n\t\t}\n\n\t\tconst swipeAmountX = this.swipeAxis === 'x' ? deltaX : 0;\n\t\tconst swipeAmountY = this.swipeAxis === 'y' ? deltaY : 0;\n\n\t\tif (this.swipeAxis === 'y') {\n\t\t\tconst towardExit = y === 'bottom' ? swipeAmountY > 0 : swipeAmountY < 0;\n\t\t\tif (!towardExit && Math.abs(swipeAmountY) < TOAST_SWIPE_THRESHOLD) {\n\t\t\t\tthis.style.setProperty('--swipe-amount-x', '0px');\n\t\t\t\tthis.style.setProperty('--swipe-amount-y', '0px');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.swipeAxis === 'x') {\n\t\t\tconst towardExit = x === 'start' ? swipeAmountX < 0 : swipeAmountX > 0;\n\t\t\tif (x !== 'center' && !towardExit && Math.abs(swipeAmountX) < TOAST_SWIPE_THRESHOLD) {\n\t\t\t\tthis.style.setProperty('--swipe-amount-x', '0px');\n\t\t\t\tthis.style.setProperty('--swipe-amount-y', '0px');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.style.setProperty('--swipe-amount-x', `${swipeAmountX}px`);\n\t\tthis.style.setProperty('--swipe-amount-y', `${swipeAmountY}px`);\n\t}\n\n\t@bound\n\tprivate onPointerUp(event: PointerEvent): void {\n\t\tif (!this.pointerStart) return;\n\t\ttry {\n\t\t\tthis.releasePointerCapture(event.pointerId);\n\t\t} catch {}\n\n\t\tconst wasSwiping = this.swiping;\n\t\tthis.swiping = false;\n\n\t\tif (!wasSwiping) {\n\t\t\tthis.pointerStart = null;\n\t\t\tthis.dragStartTime = null;\n\t\t\tthis.swipeAxis = null;\n\t\t\treturn;\n\t\t}\n\n\t\tconst swipeAmountX = Number.parseFloat(this.style.getPropertyValue('--swipe-amount-x') || '0');\n\t\tconst swipeAmountY = Number.parseFloat(this.style.getPropertyValue('--swipe-amount-y') || '0');\n\t\tconst swipeAmount = this.swipeAxis === 'x' ? swipeAmountX : swipeAmountY;\n\t\tconst swipeTime = this.dragStartTime ? Date.now() - this.dragStartTime : 0;\n\t\tconst velocity = Math.abs(swipeAmount) / Math.max(swipeTime, 1);\n\t\tconst shouldDismiss = Math.abs(swipeAmount) >= TOAST_SWIPE_THRESHOLD || velocity > 0.11;\n\n\t\tif (shouldDismiss && this.dismissible) {\n\t\t\tconst { y, x } = splitToastPosition(this.position);\n\t\t\tif (this.swipeAxis === 'x') {\n\t\t\t\tthis.swipeOutDirection = swipeAmountX < 0 ? 'left' : 'right';\n\t\t\t\tif (x === 'start') this.swipeOutDirection = 'left';\n\t\t\t\tif (x === 'end') this.swipeOutDirection = 'right';\n\t\t\t} else {\n\t\t\t\tthis.swipeOutDirection = y === 'bottom' ? 'down' : 'up';\n\t\t\t}\n\t\t\tthis.swipeOut = true;\n\t\t\tthis.syncDomState();\n\t\t\tthis.beginRemove();\n\t\t} else {\n\t\t\tthis.style.setProperty('--swipe-amount-x', '0px');\n\t\t\tthis.style.setProperty('--swipe-amount-y', '0px');\n\t\t\tthis.swipeAxis = null;\n\t\t\tthis.syncDomState();\n\t\t}\n\n\t\tthis.pointerStart = null;\n\t\tthis.dragStartTime = null;\n\t}\n\n\t@onEvent({ selector: '[data-toast-close]', type: 'click' })\n\tonCloseClick(event: Event): void {\n\t\tevent.stopPropagation();\n\t\tif (!this.dismissible) return;\n\t\tthis.beginRemove();\n\t}\n\n\t@onEvent({ selector: '[data-toast-action]', type: 'click' })\n\tonActionClick(event: MouseEvent): void {\n\t\tevent.stopPropagation();\n\t\tconst record = toastState.getSnapshot().find((toast) => toast.id === this.resolvedId);\n\t\trecord?.action?.onClick(event);\n\t\tif (this.dismissible) this.beginRemove();\n\t}\n\n\tprivate syncDomState(): void {\n\t\tconst { y, x } = splitToastPosition(this.position);\n\t\tthis.setAttribute('role', 'listitem');\n\t\tthis.dataset.mounted = String(this.mounted);\n\t\tthis.dataset.removed = String(this.removed);\n\t\tthis.dataset.swiping = String(this.swiping);\n\t\tthis.dataset.swipeOut = String(this.swipeOut);\n\t\tthis.dataset.dismissible = String(this.dismissible);\n\t\tthis.dataset.yPosition = y;\n\t\tthis.dataset.xPosition = x;\n\t\tthis.dataset.variant = this.variant ?? 'default';\n\t\tif (this.swipeOutDirection) this.dataset.swipeDirection = this.swipeOutDirection;\n\t\telse delete this.dataset.swipeDirection;\n\t}\n\n\tprivate iconForVariant(): string {\n\t\tswitch (this.variant) {\n\t\t\tcase 'success':\n\t\t\t\treturn '\u2713';\n\t\t\tcase 'error':\n\t\t\t\treturn '\u2715';\n\t\t\tcase 'warning':\n\t\t\t\treturn '!';\n\t\t\tcase 'info':\n\t\t\t\treturn 'i';\n\t\t\tdefault:\n\t\t\t\treturn '';\n\t\t}\n\t}\n\n\toverride render() {\n\t\tconst variant = this.variant ?? 'default';\n\t\tconst icon = this.iconForVariant();\n\t\tconst showIcon = variant !== 'default';\n\n\t\treturn (\n\t\t\t<div ref=\"toast\" class={`rui-toast rui-toast--${variant}`} role=\"status\" aria-live=\"off\" data-ref=\"toast\">\n\t\t\t\t{this.closeButton && variant !== 'loading' ? (\n\t\t\t\t\t<button type=\"button\" class=\"rui-toast__close\" data-toast-close aria-label=\"Close toast\">\n\t\t\t\t\t\t\u00D7\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t\t{showIcon ? (\n\t\t\t\t\t<span class=\"rui-toast__icon\" data-icon aria-hidden=\"true\">\n\t\t\t\t\t\t{variant === 'loading' ? <span class=\"rui-toast__loader\" /> : icon}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t\t<div class=\"rui-toast__content\">\n\t\t\t\t\t<div class=\"rui-toast__title\" data-title>\n\t\t\t\t\t\t{this.$.title}\n\t\t\t\t\t</div>\n\t\t\t\t\t{this.description ? (\n\t\t\t\t\t\t<div class=\"rui-toast__description\" data-description>\n\t\t\t\t\t\t\t{this.$.description}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t{this.actionLabel ? (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"rui-toast__action rui-button rui-button--outline rui-button--sm\"\n\t\t\t\t\t\tdata-toast-action\n\t\t\t\t\t>\n\t\t\t\t\t\t{this.$.actionLabel}\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t);\n\t}\n}\n", "export const RUI_TOAST_SHOW_EVENT = 'rui-toast-show';\nexport const RUI_TOAST_DISMISS_EVENT = 'rui-toast-dismiss';\n\nexport type ToastVariant = 'default' | 'info' | 'success' | 'warning' | 'error' | 'loading';\n\nexport type ToastPosition = 'top-start' | 'top-center' | 'top-end' | 'bottom-start' | 'bottom-center' | 'bottom-end';\n\nexport type ToastAction = {\n\tlabel: string;\n\tonClick: (event: MouseEvent) => void;\n};\n\nexport type ToastId = string | number;\n\nexport type ToastOptions = {\n\tid?: ToastId;\n\tdescription?: string;\n\tduration?: number;\n\taction?: ToastAction;\n\tdismissible?: boolean;\n\tcloseButton?: boolean;\n\tposition?: ToastPosition;\n};\n\nexport type ToastRecord = {\n\tid: ToastId;\n\ttitle: string;\n\tdescription?: string;\n\tvariant: ToastVariant;\n\tduration?: number;\n\taction?: ToastAction;\n\tdismissible: boolean;\n\tcloseButton?: boolean;\n\tposition?: ToastPosition;\n\t/** Marks the toast for animated exit; toaster removes after exit. */\n\tdelete?: boolean;\n};\n\nexport type ToastDismissDetail = { id?: ToastId };\nexport type ToastShowDetail = Omit<ToastRecord, 'dismissible'> & { dismissible?: boolean };\n\nexport type PromiseToastMessages<T> = {\n\tloading: string;\n\tsuccess: string | ((data: T) => string);\n\terror: string | ((error: unknown) => string);\n\tdescription?: string | ((data: T | unknown) => string);\n\tduration?: number;\n\taction?: ToastAction;\n\tcloseButton?: boolean;\n\tposition?: ToastPosition;\n};\n\nexport const TOAST_LIFETIME = 4000;\nexport const TOAST_WIDTH = 356;\nexport const TOAST_GAP = 14;\nexport const TOAST_VIEWPORT_OFFSET = 24;\nexport const TOAST_VISIBLE_AMOUNT = 3;\nexport const TOAST_SWIPE_THRESHOLD = 45;\nexport const TOAST_EXIT_MS = 200;\n\nexport const DEFAULT_TOAST_POSITION: ToastPosition = 'bottom-end';\n\nexport function splitToastPosition(position: ToastPosition): {\n\ty: 'top' | 'bottom';\n\tx: 'start' | 'center' | 'end';\n} {\n\tconst [y, x] = position.split('-') as ['top' | 'bottom', 'start' | 'center' | 'end'];\n\treturn { y, x };\n}\n", "import type { PromiseToastMessages, ToastId, ToastOptions, ToastRecord, ToastVariant } from './toast-context';\n\nexport type ToastSubscriber = (toasts: ToastRecord[]) => void;\n\nlet toastCounter = 1;\n\nfunction nextId(): number {\n\treturn toastCounter++;\n}\n\nfunction resolveMessage<T>(message: string | ((value: T) => string), value: T): string {\n\treturn typeof message === 'function' ? message(value) : message;\n}\n\nclass ToastState {\n\tprivate subscribers: ToastSubscriber[] = [];\n\tprivate toasts: ToastRecord[] = [];\n\n\tsubscribe = (subscriber: ToastSubscriber): (() => void) => {\n\t\tthis.subscribers.push(subscriber);\n\t\tsubscriber(this.toasts);\n\t\treturn () => {\n\t\t\tconst index = this.subscribers.indexOf(subscriber);\n\t\t\tif (index >= 0) this.subscribers.splice(index, 1);\n\t\t};\n\t};\n\n\tgetSnapshot = (): ToastRecord[] => this.toasts;\n\n\tprivate publish(): void {\n\t\tconst snapshot = this.toasts;\n\t\tfor (const subscriber of this.subscribers) {\n\t\t\tsubscriber(snapshot);\n\t\t}\n\t}\n\n\tcreate = (title: string, options: ToastOptions & { variant?: ToastVariant } = {}): ToastId => {\n\t\tconst id = options.id ?? nextId();\n\t\tconst dismissible = options.dismissible ?? true;\n\t\tconst existingIndex = this.toasts.findIndex((toast) => toast.id === id);\n\n\t\tconst next: ToastRecord = {\n\t\t\tid,\n\t\t\ttitle,\n\t\t\tdescription: options.description,\n\t\t\tvariant: options.variant ?? 'default',\n\t\t\tduration: options.duration,\n\t\t\taction: options.action,\n\t\t\tdismissible,\n\t\t\tcloseButton: options.closeButton,\n\t\t\tposition: options.position,\n\t\t\tdelete: false,\n\t\t};\n\n\t\tif (existingIndex >= 0) {\n\t\t\tthis.toasts = this.toasts.map((toast) => (toast.id === id ? { ...toast, ...next, delete: false } : toast));\n\t\t} else {\n\t\t\tthis.toasts = [next, ...this.toasts];\n\t\t}\n\n\t\tthis.publish();\n\t\treturn id;\n\t};\n\n\tdismiss = (id?: ToastId): void => {\n\t\tif (id == null) {\n\t\t\tif (this.toasts.length === 0) return;\n\t\t\tthis.toasts = this.toasts.map((toast) => ({ ...toast, delete: true }));\n\t\t} else {\n\t\t\tconst target = this.toasts.find((toast) => toast.id === id);\n\t\t\tif (!target || target.delete) return;\n\t\t\tthis.toasts = this.toasts.map((toast) => (toast.id === id ? { ...toast, delete: true } : toast));\n\t\t}\n\t\tthis.publish();\n\t};\n\n\tremove = (id: ToastId): void => {\n\t\tthis.toasts = this.toasts.filter((toast) => toast.id !== id);\n\t\tthis.publish();\n\t};\n\n\t/** Drop every toast from the store (tests, Storybook resets). */\n\tclear = (): void => {\n\t\tif (this.toasts.length === 0) return;\n\t\tthis.toasts = [];\n\t\tthis.publish();\n\t};\n\n\tmessage = (title: string, options?: ToastOptions): ToastId => this.create(title, options);\n\n\tsuccess = (title: string, options?: ToastOptions): ToastId =>\n\t\tthis.create(title, { ...options, variant: 'success' });\n\n\terror = (title: string, options?: ToastOptions): ToastId => this.create(title, { ...options, variant: 'error' });\n\n\tinfo = (title: string, options?: ToastOptions): ToastId => this.create(title, { ...options, variant: 'info' });\n\n\twarning = (title: string, options?: ToastOptions): ToastId =>\n\t\tthis.create(title, { ...options, variant: 'warning' });\n\n\tloading = (title: string, options?: ToastOptions): ToastId =>\n\t\tthis.create(title, { ...options, variant: 'loading', duration: options?.duration ?? Number.POSITIVE_INFINITY });\n\n\tpromise = <T>(promise: Promise<T> | (() => Promise<T>), messages: PromiseToastMessages<T>): ToastId => {\n\t\tconst id = this.loading(messages.loading, {\n\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\taction: messages.action,\n\t\t\tcloseButton: messages.closeButton,\n\t\t\tposition: messages.position,\n\t\t\tdescription: typeof messages.description === 'string' ? messages.description : undefined,\n\t\t});\n\n\t\tconst pending = typeof promise === 'function' ? promise() : promise;\n\n\t\tpending\n\t\t\t.then((data) => {\n\t\t\t\tconst description =\n\t\t\t\t\ttypeof messages.description === 'function' ? messages.description(data) : messages.description;\n\t\t\t\tthis.create(resolveMessage(messages.success, data), {\n\t\t\t\t\tid,\n\t\t\t\t\tvariant: 'success',\n\t\t\t\t\tdescription,\n\t\t\t\t\tduration: messages.duration,\n\t\t\t\t\taction: messages.action,\n\t\t\t\t\tcloseButton: messages.closeButton,\n\t\t\t\t\tposition: messages.position,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst description =\n\t\t\t\t\ttypeof messages.description === 'function' ? messages.description(error) : messages.description;\n\t\t\t\tthis.create(resolveMessage(messages.error, error), {\n\t\t\t\t\tid,\n\t\t\t\t\tvariant: 'error',\n\t\t\t\t\tdescription,\n\t\t\t\t\tduration: messages.duration,\n\t\t\t\t\taction: messages.action,\n\t\t\t\t\tcloseButton: messages.closeButton,\n\t\t\t\t\tposition: messages.position,\n\t\t\t\t});\n\t\t\t});\n\n\t\treturn id;\n\t};\n}\n\nexport const toastState = new ToastState();\n", "import { RadiantElement, bound, customElement, onEvent, onUpdated, prop, state } from '@ecopages/radiant';\nimport {\n\tDEFAULT_TOAST_POSITION,\n\tRUI_TOAST_DISMISS_EVENT,\n\tRUI_TOAST_SHOW_EVENT,\n\tTOAST_GAP,\n\tTOAST_LIFETIME,\n\tTOAST_VIEWPORT_OFFSET,\n\tTOAST_VISIBLE_AMOUNT,\n\tTOAST_WIDTH,\n\ttype ToastDismissDetail,\n\ttype ToastPosition,\n\ttype ToastRecord,\n\ttype ToastShowDetail,\n\tsplitToastPosition,\n} from './toast-context';\nimport { toastState } from './toast-state';\nimport type { RuiToast } from './toast.script';\nimport './toast.script';\n\nexport type RuiToasterProps = {\n\t/** Corner / edge placement. Default: `bottom-end`. */\n\tposition?: ToastPosition;\n\t/** Default lifetime in ms. Default: `4000`. */\n\tduration?: number;\n\t/**\n\t * Max toasts shown in the stack at once (older ones wait in queue).\n\t * Default: `3`.\n\t */\n\tvisibleToasts?: number;\n\t/** Show a close button on every toast. */\n\tcloseButton?: boolean;\n\t/**\n\t * Always show the stack expanded with full gaps.\n\t * Default `false`: toasts collapse behind the front one (Sonner-style peek)\n\t * and expand on hover.\n\t */\n\texpand?: boolean;\n\t/** Gap between toasts when expanded, in px. Default: `14`. */\n\tgap?: number;\n\t/** Viewport inset in px. Default: `24`. */\n\toffset?: number;\n};\n\ntype RuiToasterBindings = {\n\tposition: ToastPosition;\n\ttoasts: ToastRecord[];\n};\n\nfunction isInsideToaster(node: EventTarget | null, root: Element): boolean {\n\treturn node instanceof Node && root.contains(node);\n}\n\n/**\n * `<rui-toaster>` \u2014 fixed viewport that renders the toast stack.\n *\n * @element rui-toaster\n */\n@customElement('rui-toaster')\nexport class RuiToaster extends RadiantElement<RuiToasterBindings> {\n\t@prop({ type: String, reflect: true, defaultValue: DEFAULT_TOAST_POSITION }) position: ToastPosition;\n\t@prop({ type: Number, defaultValue: TOAST_LIFETIME }) duration: number;\n\t@prop({ type: Number, defaultValue: TOAST_VISIBLE_AMOUNT }) visibleToasts: number;\n\t@prop({ type: Boolean, defaultValue: false }) closeButton: boolean;\n\t@prop({ type: Boolean, defaultValue: false }) expand: boolean;\n\t@prop({ type: Number, defaultValue: TOAST_GAP }) gap: number;\n\t@prop({ type: Number, defaultValue: TOAST_VIEWPORT_OFFSET }) offset: number;\n\n\t@state toasts: ToastRecord[] = [];\n\n\tprivate expanded = false;\n\tprivate interacting = false;\n\tprivate unsubscribe: (() => void) | null = null;\n\tprivate visibilityHandler: (() => void) | null = null;\n\tprivate readonly heights = new Map<string, number>();\n\tprivate readonly observers = new Map<string, ResizeObserver>();\n\tprivate layoutFrame: number | null = null;\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback();\n\t\tthis.syncHostPosition();\n\t\tthis.unsubscribe = toastState.subscribe((toasts) => {\n\t\t\tthis.toasts = toasts;\n\t\t\tif (toasts.length === 0) {\n\t\t\t\tthis.resetLayoutState();\n\t\t\t}\n\t\t\tthis.scheduleLayoutSync();\n\t\t});\n\t\tthis.visibilityHandler = () => this.syncPauseState();\n\t\tdocument.addEventListener('visibilitychange', this.visibilityHandler);\n\t}\n\n\toverride disconnectedCallback(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.unsubscribe = null;\n\t\tif (this.visibilityHandler) {\n\t\t\tdocument.removeEventListener('visibilitychange', this.visibilityHandler);\n\t\t\tthis.visibilityHandler = null;\n\t\t}\n\t\tdocument.removeEventListener('pointerup', this.onPointerUp);\n\t\tdocument.removeEventListener('pointercancel', this.onPointerUp);\n\t\tif (this.layoutFrame != null) cancelAnimationFrame(this.layoutFrame);\n\t\tthis.resetLayoutState();\n\t\tsuper.disconnectedCallback();\n\t}\n\n\t@onUpdated(['position', 'duration', 'visibleToasts', 'closeButton', 'expand', 'gap', 'offset'])\n\tonConfigUpdated(): void {\n\t\tthis.syncHostPosition();\n\t\tthis.scheduleLayoutSync();\n\t}\n\n\t@onEvent({ document: true, type: RUI_TOAST_SHOW_EVENT })\n\tonDocumentShow(event: Event): void {\n\t\tconst detail = (event as CustomEvent<ToastShowDetail>).detail;\n\t\tif (!detail?.title) return;\n\t\ttoastState.create(detail.title, {\n\t\t\tid: detail.id,\n\t\t\tdescription: detail.description,\n\t\t\tvariant: detail.variant,\n\t\t\tduration: detail.duration,\n\t\t\taction: detail.action,\n\t\t\tdismissible: detail.dismissible,\n\t\t\tcloseButton: detail.closeButton,\n\t\t\tposition: detail.position,\n\t\t});\n\t}\n\n\t@onEvent({ document: true, type: RUI_TOAST_DISMISS_EVENT })\n\tonDocumentDismiss(event: Event): void {\n\t\tconst detail = (event as CustomEvent<ToastDismissDetail>).detail;\n\t\ttoastState.dismiss(detail?.id);\n\t}\n\n\t@onEvent({ selector: 'rui-toast', type: 'rui-toast-mounted' })\n\tonToastMounted(): void {\n\t\tthis.observeToasts();\n\t\tthis.syncPauseState();\n\t}\n\n\tprivate filteredToasts(): ToastRecord[] {\n\t\tconst forPosition = this.toasts.filter((toast) => (toast.position ?? this.position) === this.position);\n\t\tconst active: ToastRecord[] = [];\n\t\tconst exiting: ToastRecord[] = [];\n\n\t\tfor (const toast of forPosition) {\n\t\t\tif (toast.delete) exiting.push(toast);\n\t\t\telse active.push(toast);\n\t\t}\n\n\t\treturn [...active.slice(0, this.visibleToasts), ...exiting];\n\t}\n\n\tprivate syncHostPosition(): void {\n\t\tconst { y, x } = splitToastPosition(this.position);\n\t\tthis.dataset.yPosition = y;\n\t\tthis.dataset.xPosition = x;\n\t\tthis.style.setProperty('--width', `${TOAST_WIDTH}px`);\n\t\tthis.style.setProperty('--gap', `${this.gap}px`);\n\t\tthis.style.setProperty('--viewport-offset', `${this.offset}px`);\n\t}\n\n\tprivate isStackExpanded(): boolean {\n\t\treturn this.expanded || this.expand;\n\t}\n\n\tprivate isPaused(): boolean {\n\t\treturn this.isStackExpanded() || this.interacting || document.hidden;\n\t}\n\n\tprivate resetLayoutState(): void {\n\t\tfor (const observer of this.observers.values()) observer.disconnect();\n\t\tthis.observers.clear();\n\t\tthis.heights.clear();\n\t\tthis.expanded = false;\n\t\tthis.interacting = false;\n\t\tconst list = this.querySelector<HTMLOListElement>('.rui-toaster');\n\t\tif (list) {\n\t\t\tlist.style.height = '0px';\n\t\t\tlist.dataset.expanded = 'false';\n\t\t}\n\t\tthis.dataset.expanded = 'false';\n\t}\n\n\tprivate syncPauseState(): void {\n\t\tconst paused = this.isPaused();\n\t\tfor (const el of this.querySelectorAll('rui-toast')) {\n\t\t\t(el as RuiToast).setPaused(paused);\n\t\t}\n\t\tthis.patchStackLayout();\n\t}\n\n\t/**\n\t * Measure + layout on the next frame. Re-reads `:hover` because emptying the\n\t * stack under the cursor can skip `pointerout`, leaving hold/expand stale.\n\t */\n\tprivate scheduleLayoutSync(): void {\n\t\tif (this.layoutFrame != null) cancelAnimationFrame(this.layoutFrame);\n\t\tthis.layoutFrame = requestAnimationFrame(() => {\n\t\t\tthis.layoutFrame = null;\n\t\t\tif (this.toasts.length > 0 && !this.interacting) {\n\t\t\t\tconst list = this.querySelector('.rui-toaster');\n\t\t\t\tconst hovered = Boolean(list?.matches(':hover') || this.matches(':hover'));\n\t\t\t\tthis.expanded = hovered;\n\t\t\t}\n\t\t\tthis.observeToasts();\n\t\t\tthis.syncPauseState();\n\t\t});\n\t}\n\n\tprivate measureToast(el: RuiToast): number {\n\t\tconst prevHeight = el.style.height;\n\t\tconst prevOverflow = el.style.overflow;\n\t\tel.style.height = 'auto';\n\t\tel.style.overflow = 'visible';\n\t\tconst inner = el.querySelector('.rui-toast');\n\t\tconst height = Math.round(inner instanceof HTMLElement ? inner.offsetHeight : el.offsetHeight) || 64;\n\t\tel.style.height = prevHeight;\n\t\tel.style.overflow = prevOverflow;\n\t\treturn height;\n\t}\n\n\tprivate observeToasts(): void {\n\t\tconst list = this.querySelector('.rui-toaster');\n\t\tif (!list) return;\n\n\t\tconst els = [...list.querySelectorAll('rui-toast')] as RuiToast[];\n\t\tconst seen = new Set<string>();\n\n\t\tfor (const el of els) {\n\t\t\tconst id = el.toastId;\n\t\t\tif (!id) continue;\n\t\t\tseen.add(id);\n\n\t\t\tconst target = el.querySelector('.rui-toast') ?? el;\n\n\t\t\tif (!this.observers.has(id)) {\n\t\t\t\tconst observer = new ResizeObserver(() => {\n\t\t\t\t\tconst height = this.measureToast(el);\n\t\t\t\t\tif (this.heights.get(id) === height) return;\n\t\t\t\t\tthis.heights.set(id, height);\n\t\t\t\t\tthis.patchStackLayout();\n\t\t\t\t});\n\t\t\t\tobserver.observe(target);\n\t\t\t\tthis.observers.set(id, observer);\n\t\t\t}\n\n\t\t\tthis.heights.set(id, this.measureToast(el));\n\t\t}\n\n\t\tfor (const [id, observer] of [...this.observers]) {\n\t\t\tif (seen.has(id)) continue;\n\t\t\tobserver.disconnect();\n\t\t\tthis.observers.delete(id);\n\t\t\tthis.heights.delete(id);\n\t\t}\n\t}\n\n\tprivate patchStackLayout(): void {\n\t\tconst list = this.querySelector<HTMLOListElement>('.rui-toaster');\n\t\tif (!list) return;\n\n\t\tconst expanded = this.isStackExpanded();\n\t\tconst { y } = splitToastPosition(this.position);\n\t\tconst lift = y === 'bottom' ? -1 : 1;\n\n\t\tthis.dataset.expanded = String(expanded);\n\t\tlist.dataset.expanded = String(expanded);\n\n\t\tconst els = ([...list.querySelectorAll('rui-toast')] as RuiToast[]).filter(\n\t\t\t(el) => el.dataset.mounted === 'true' && el.dataset.removed !== 'true',\n\t\t);\n\n\t\tif (els.length === 0) {\n\t\t\tlist.style.height = '0px';\n\t\t\treturn;\n\t\t}\n\n\t\tconst heights = els.map((el) => {\n\t\t\tconst measured = this.heights.get(el.toastId) ?? this.measureToast(el);\n\t\t\tthis.heights.set(el.toastId, measured);\n\t\t\treturn measured;\n\t\t});\n\t\tconst frontHeight = heights[0] ?? 64;\n\n\t\tlet accumulated = 0;\n\t\tfor (let index = 0; index < els.length; index += 1) {\n\t\t\tconst el = els[index];\n\t\t\tif (!el) continue;\n\t\t\tconst height = heights[index] ?? 64;\n\t\t\tconst isFront = index === 0;\n\n\t\t\tel.dataset.index = String(index);\n\t\t\tel.dataset.front = String(isFront);\n\t\t\tel.dataset.expanded = String(expanded);\n\t\t\tel.style.setProperty('--z-index', String(els.length - index));\n\n\t\t\tif (expanded) {\n\t\t\t\tel.style.setProperty('--y', `translateY(${lift * accumulated}px)`);\n\t\t\t\tel.style.height = `${height}px`;\n\t\t\t\tel.style.overflow = 'visible';\n\t\t\t\taccumulated += height + this.gap;\n\t\t\t} else if (isFront) {\n\t\t\t\tel.style.setProperty('--y', 'translateY(0px)');\n\t\t\t\tel.style.height = `${height}px`;\n\t\t\t\tel.style.overflow = 'visible';\n\t\t\t} else {\n\t\t\t\t// Keep scaling for every depth \u2014 clamping (e.g. at 0.92) makes toasts\n\t\t\t\t// past the default visibleToasts=3 look identical and stack poorly.\n\t\t\t\tconst scale = Math.max(0.7, 1 - index * 0.05);\n\t\t\t\tel.style.setProperty('--y', `translateY(${lift * index * this.gap}px) scale(${scale})`);\n\t\t\t\tel.style.height = `${frontHeight}px`;\n\t\t\t\tel.style.overflow = 'hidden';\n\t\t\t}\n\t\t}\n\n\t\tconst stackHeight = expanded\n\t\t\t? Math.max(0, accumulated > 0 ? accumulated - this.gap : frontHeight)\n\t\t\t: frontHeight + Math.max(0, els.length - 1) * this.gap;\n\n\t\tlist.style.height = `${stackHeight}px`;\n\t}\n\n\t@bound\n\tprivate onPointerOver(event: PointerEvent): void {\n\t\tif (isInsideToaster(event.relatedTarget, this)) return;\n\t\tthis.expanded = true;\n\t\tthis.syncPauseState();\n\t}\n\n\t@bound\n\tprivate onPointerOut(event: PointerEvent): void {\n\t\tif (isInsideToaster(event.relatedTarget, this)) return;\n\t\tif (this.interacting) return;\n\t\tthis.expanded = false;\n\t\tthis.syncPauseState();\n\t}\n\n\t@bound\n\tprivate onPointerDown(): void {\n\t\tthis.interacting = true;\n\t\tthis.expanded = true;\n\t\tthis.syncPauseState();\n\t\tdocument.addEventListener('pointerup', this.onPointerUp, { once: true });\n\t\tdocument.addEventListener('pointercancel', this.onPointerUp, { once: true });\n\t}\n\n\t/** End interaction; collapse only when the pointer is no longer over the toaster. */\n\t@bound\n\tprivate onPointerUp(): void {\n\t\tif (!this.interacting) return;\n\t\tthis.interacting = false;\n\t\tconst hovered = this.matches(':hover') || this.querySelector('rui-toast:hover');\n\t\tif (!hovered) this.expanded = false;\n\t\tthis.syncPauseState();\n\t}\n\n\toverride render() {\n\t\tconst filtered = this.filteredToasts();\n\n\t\treturn (\n\t\t\t<section\n\t\t\t\tclass=\"rui-toaster-region\"\n\t\t\t\taria-label=\"Notifications\"\n\t\t\t\taria-live=\"polite\"\n\t\t\t\taria-relevant=\"additions text\"\n\t\t\t\taria-atomic=\"false\"\n\t\t\t\ttabIndex={-1}\n\t\t\t>\n\t\t\t\t<ol\n\t\t\t\t\tclass=\"rui-toaster\"\n\t\t\t\t\tdata-rui-toaster\n\t\t\t\t\ton:pointerover={this.onPointerOver}\n\t\t\t\t\ton:pointerout={this.onPointerOut}\n\t\t\t\t\ton:pointerdown={this.onPointerDown}\n\t\t\t\t>\n\t\t\t\t\t{filtered.map((toast) => {\n\t\t\t\t\t\tconst duration =\n\t\t\t\t\t\t\ttoast.duration ?? (toast.variant === 'loading' ? Number.POSITIVE_INFINITY : this.duration);\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<rui-toast\n\t\t\t\t\t\t\t\tkey={String(toast.id)}\n\t\t\t\t\t\t\t\tprop:toastId={String(toast.id)}\n\t\t\t\t\t\t\t\tprop:title={toast.title}\n\t\t\t\t\t\t\t\tprop:description={toast.description ?? ''}\n\t\t\t\t\t\t\t\tprop:variant={toast.variant}\n\t\t\t\t\t\t\t\tprop:duration={duration}\n\t\t\t\t\t\t\t\tprop:dismissible={toast.dismissible}\n\t\t\t\t\t\t\t\tprop:closeButton={toast.closeButton ?? this.closeButton}\n\t\t\t\t\t\t\t\tprop:actionLabel={toast.action?.label ?? ''}\n\t\t\t\t\t\t\t\tprop:position={toast.position ?? this.position}\n\t\t\t\t\t\t\t\tprop:markedDelete={Boolean(toast.delete)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</ol>\n\t\t\t</section>\n\t\t);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\n\nconst RADIANT_VIEW_ELEMENT = Symbol.for('@ecopages/storybook-radiant.viewElement');\nconst RADIANT_SCRIPT_MODULE = Symbol.for('@ecopages/storybook-radiant.scriptModule');\nconst RADIANT_SCRIPT_EXPORT = Symbol.for('@ecopages/storybook-radiant.scriptExport');\n\nexport type RadiantViewComponent<TArgs = unknown> = ((args: TArgs) => JsxRenderable) & {\n\t[RADIANT_VIEW_ELEMENT]?: CustomElementConstructor;\n\t[RADIANT_SCRIPT_MODULE]?: string;\n\t[RADIANT_SCRIPT_EXPORT]?: string;\n};\n\nfunction linkViewToElement<TArgs>(\n\tview: RadiantViewComponent<TArgs>,\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n): void {\n\tview[RADIANT_VIEW_ELEMENT] = element;\n\n\tconst ssrModule = element[RADIANT_SCRIPT_MODULE];\n\tif (ssrModule) {\n\t\tview[RADIANT_SCRIPT_MODULE] = ssrModule;\n\t\tview[RADIANT_SCRIPT_EXPORT] = element[RADIANT_SCRIPT_EXPORT] ?? element.name;\n\t}\n}\n\n/** Link a JSX view export to its RadiantElement class (same symbols as the Storybook framework). */\nexport function defineRadiantView<TArgs>(\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n\trender: (args: TArgs) => JsxRenderable,\n): RadiantViewComponent<TArgs> {\n\tconst view = ((args: TArgs) => render(args)) as RadiantViewComponent<TArgs>;\n\tlinkViewToElement(view, element);\n\treturn view;\n}\n\n/** Re-copy SSR metadata from the linked element (e.g. after HMR). */\nexport function syncRadiantViewMetadata(view: RadiantViewComponent): void {\n\tconst element = view[RADIANT_VIEW_ELEMENT];\n\tif (element) {\n\t\tlinkViewToElement(view, element);\n\t}\n}\n", "import type { WithChildren, RadiantSlotProps } from '../../../types';\nimport { defineRadiantView } from '../../../lib/radiant-view';\nimport type { RuiToastProps } from './toast.script';\nimport { RuiToast as RuiToastElement } from './toast.script';\nimport type { RuiToasterProps } from './toaster.script';\nimport { RuiToaster as RuiToasterElement } from './toaster.script';\nimport './toast.css';\n\nexport type RuiToastViewProps = RuiToastProps & RadiantSlotProps;\n\nexport const RuiToast = defineRadiantView(\n\tRuiToastElement,\n\t({\n\t\tslot,\n\t\ttoastId,\n\t\ttitle,\n\t\tdescription,\n\t\tvariant,\n\t\tduration,\n\t\tdismissible,\n\t\tcloseButton,\n\t\tactionLabel,\n\t\tposition,\n\t\tmarkedDelete,\n\t}: RuiToastViewProps) => (\n\t\t<rui-toast\n\t\t\tslot={slot}\n\t\t\tprop:toastId={toastId != null ? String(toastId) : undefined}\n\t\t\tprop:title={title}\n\t\t\tprop:description={description}\n\t\t\tprop:variant={variant}\n\t\t\tprop:duration={duration}\n\t\t\tprop:dismissible={dismissible}\n\t\t\tprop:closeButton={closeButton}\n\t\t\tprop:actionLabel={actionLabel}\n\t\t\tprop:position={position}\n\t\t\tprop:markedDelete={markedDelete}\n\t\t/>\n\t),\n);\n\nexport type RuiToasterViewProps = WithChildren<RuiToasterProps & RadiantSlotProps>;\n\nexport const RuiToaster = defineRadiantView(\n\tRuiToasterElement,\n\t({ slot, position, duration, visibleToasts, closeButton, expand, gap, offset, children }: RuiToasterViewProps) => (\n\t\t<rui-toaster\n\t\t\tslot={slot}\n\t\t\tprop:position={position}\n\t\t\tprop:duration={duration}\n\t\t\tprop:visibleToasts={visibleToasts}\n\t\t\tprop:closeButton={closeButton}\n\t\t\tprop:expand={expand}\n\t\t\tprop:gap={gap}\n\t\t\tprop:offset={offset}\n\t\t>\n\t\t\t{children}\n\t\t</rui-toaster>\n\t),\n);\n", "import {\n\tRUI_TOAST_DISMISS_EVENT,\n\tRUI_TOAST_SHOW_EVENT,\n\ttype PromiseToastMessages,\n\ttype ToastDismissDetail,\n\ttype ToastId,\n\ttype ToastOptions,\n\ttype ToastShowDetail,\n} from './toast-context';\nimport { toastState } from './toast-state';\n\nexport type ToastCallable = {\n\t(title: string, options?: ToastOptions): ToastId;\n\tmessage: (title: string, options?: ToastOptions) => ToastId;\n\tsuccess: (title: string, options?: ToastOptions) => ToastId;\n\terror: (title: string, options?: ToastOptions) => ToastId;\n\tinfo: (title: string, options?: ToastOptions) => ToastId;\n\twarning: (title: string, options?: ToastOptions) => ToastId;\n\tloading: (title: string, options?: ToastOptions) => ToastId;\n\tpromise: <T>(promise: Promise<T> | (() => Promise<T>), messages: PromiseToastMessages<T>) => ToastId;\n\tdismiss: (id?: ToastId) => void;\n\t/** Remove all toasts from the store (Storybook / test resets). */\n\tclear: () => void;\n};\n\n/**\n * Primary imperative toast API (Sonner-shaped). Requires a mounted `<rui-toaster>`.\n * Prefer this over {@link showToast} in application code.\n */\nexport const toast: ToastCallable = Object.assign(\n\t(title: string, options?: ToastOptions) => toastState.create(title, options),\n\t{\n\t\tmessage: (title: string, options?: ToastOptions) => toastState.message(title, options),\n\t\tsuccess: (title: string, options?: ToastOptions) => toastState.success(title, options),\n\t\terror: (title: string, options?: ToastOptions) => toastState.error(title, options),\n\t\tinfo: (title: string, options?: ToastOptions) => toastState.info(title, options),\n\t\twarning: (title: string, options?: ToastOptions) => toastState.warning(title, options),\n\t\tloading: (title: string, options?: ToastOptions) => toastState.loading(title, options),\n\t\tpromise: <T>(promise: Promise<T> | (() => Promise<T>), messages: PromiseToastMessages<T>) =>\n\t\t\ttoastState.promise(promise, messages),\n\t\tdismiss: (id?: ToastId) => toastState.dismiss(id),\n\t\tclear: () => toastState.clear(),\n\t},\n);\n\n/**\n * DOM event bridge: dispatches `rui-toast-show` on `document` for hosts that listen globally.\n * Application code should use {@link toast} unless you intentionally decouple via custom events.\n */\nexport function showToast(detail: ToastShowDetail): void {\n\tdocument.dispatchEvent(\n\t\tnew CustomEvent(RUI_TOAST_SHOW_EVENT, {\n\t\t\tdetail,\n\t\t\tbubbles: true,\n\t\t\tcomposed: true,\n\t\t}),\n\t);\n}\n\n/**\n * DOM event bridge: dispatches `rui-toast-dismiss` on `document`.\n * Application code should use {@link toast.dismiss} unless you intentionally decouple via custom events.\n */\nexport function dismissToast(id?: ToastId): void {\n\tconst detail: ToastDismissDetail = id == null ? {} : { id };\n\tdocument.dispatchEvent(\n\t\tnew CustomEvent(RUI_TOAST_DISMISS_EVENT, {\n\t\t\tdetail,\n\t\t\tbubbles: true,\n\t\t\tcomposed: true,\n\t\t}),\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RadiantElement", "bound", "customElement", "onEvent", "onUpdated", "prop", "query", "RUI_TOAST_SHOW_EVENT", "RUI_TOAST_DISMISS_EVENT", "TOAST_LIFETIME", "TOAST_WIDTH", "TOAST_GAP", "TOAST_VIEWPORT_OFFSET", "TOAST_VISIBLE_AMOUNT", "TOAST_SWIPE_THRESHOLD", "TOAST_EXIT_MS", "DEFAULT_TOAST_POSITION", "splitToastPosition", "position", "y", "x", "toastCounter", "nextId", "resolveMessage", "message", "value", "ToastState", "subscriber", "index", "snapshot", "title", "options", "id", "dismissible", "existingIndex", "toast", "next", "target", "promise", "messages", "data", "description", "error", "toastState", "RuiToast", "customElement", "RadiantElement", "prop", "DEFAULT_TOAST_POSITION", "query", "isReconnect", "id", "toastState", "onUpdated", "paused", "raw", "asNumber", "bound", "event", "y", "x", "splitToastPosition", "deltaX", "deltaY", "swipeAmountX", "swipeAmountY", "towardExit", "wasSwiping", "swipeAmount", "swipeTime", "velocity", "onEvent", "toast", "variant", "icon", "showIcon", "RadiantElement", "bound", "customElement", "onEvent", "onUpdated", "prop", "state", "isInsideToaster", "node", "root", "RuiToaster", "customElement", "RadiantElement", "prop", "DEFAULT_TOAST_POSITION", "state", "toastState", "toasts", "onUpdated", "onEvent", "RUI_TOAST_SHOW_EVENT", "event", "detail", "RUI_TOAST_DISMISS_EVENT", "forPosition", "toast", "active", "exiting", "y", "x", "splitToastPosition", "observer", "list", "paused", "el", "hovered", "prevHeight", "prevOverflow", "inner", "height", "els", "seen", "id", "target", "expanded", "lift", "heights", "measured", "frontHeight", "accumulated", "index", "isFront", "scale", "stackHeight", "bound", "filtered", "duration", "RADIANT_VIEW_ELEMENT", "RADIANT_SCRIPT_MODULE", "RADIANT_SCRIPT_EXPORT", "linkViewToElement", "view", "element", "ssrModule", "defineRadiantView", "render", "args", "RuiToast", "defineRadiantView", "slot", "toastId", "title", "description", "variant", "duration", "dismissible", "closeButton", "actionLabel", "position", "markedDelete", "RuiToaster", "visibleToasts", "expand", "gap", "offset", "children", "toast", "title", "options", "toastState", "promise", "messages", "id", "showToast", "detail", "RUI_TOAST_SHOW_EVENT", "dismissToast", "RUI_TOAST_DISMISS_EVENT"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type PromiseToastMessages, type ToastId, type ToastOptions, type ToastShowDetail } from './toast-context';
|
|
2
|
+
export type ToastCallable = {
|
|
3
|
+
(title: string, options?: ToastOptions): ToastId;
|
|
4
|
+
message: (title: string, options?: ToastOptions) => ToastId;
|
|
5
|
+
success: (title: string, options?: ToastOptions) => ToastId;
|
|
6
|
+
error: (title: string, options?: ToastOptions) => ToastId;
|
|
7
|
+
info: (title: string, options?: ToastOptions) => ToastId;
|
|
8
|
+
warning: (title: string, options?: ToastOptions) => ToastId;
|
|
9
|
+
loading: (title: string, options?: ToastOptions) => ToastId;
|
|
10
|
+
promise: <T>(promise: Promise<T> | (() => Promise<T>), messages: PromiseToastMessages<T>) => ToastId;
|
|
11
|
+
dismiss: (id?: ToastId) => void;
|
|
12
|
+
/** Remove all toasts from the store (Storybook / test resets). */
|
|
13
|
+
clear: () => void;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Primary imperative toast API (Sonner-shaped). Requires a mounted `<rui-toaster>`.
|
|
17
|
+
* Prefer this over {@link showToast} in application code.
|
|
18
|
+
*/
|
|
19
|
+
export declare const toast: ToastCallable;
|
|
20
|
+
/**
|
|
21
|
+
* DOM event bridge: dispatches `rui-toast-show` on `document` for hosts that listen globally.
|
|
22
|
+
* Application code should use {@link toast} unless you intentionally decouple via custom events.
|
|
23
|
+
*/
|
|
24
|
+
export declare function showToast(detail: ToastShowDetail): void;
|
|
25
|
+
/**
|
|
26
|
+
* DOM event bridge: dispatches `rui-toast-dismiss` on `document`.
|
|
27
|
+
* Application code should use {@link toast.dismiss} unless you intentionally decouple via custom events.
|
|
28
|
+
*/
|
|
29
|
+
export declare function dismissToast(id?: ToastId): void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export declare const RUI_TOAST_SHOW_EVENT = "rui-toast-show";
|
|
2
|
+
export declare const RUI_TOAST_DISMISS_EVENT = "rui-toast-dismiss";
|
|
3
|
+
export type ToastVariant = 'default' | 'info' | 'success' | 'warning' | 'error' | 'loading';
|
|
4
|
+
export type ToastPosition = 'top-start' | 'top-center' | 'top-end' | 'bottom-start' | 'bottom-center' | 'bottom-end';
|
|
5
|
+
export type ToastAction = {
|
|
6
|
+
label: string;
|
|
7
|
+
onClick: (event: MouseEvent) => void;
|
|
8
|
+
};
|
|
9
|
+
export type ToastId = string | number;
|
|
10
|
+
export type ToastOptions = {
|
|
11
|
+
id?: ToastId;
|
|
12
|
+
description?: string;
|
|
13
|
+
duration?: number;
|
|
14
|
+
action?: ToastAction;
|
|
15
|
+
dismissible?: boolean;
|
|
16
|
+
closeButton?: boolean;
|
|
17
|
+
position?: ToastPosition;
|
|
18
|
+
};
|
|
19
|
+
export type ToastRecord = {
|
|
20
|
+
id: ToastId;
|
|
21
|
+
title: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
variant: ToastVariant;
|
|
24
|
+
duration?: number;
|
|
25
|
+
action?: ToastAction;
|
|
26
|
+
dismissible: boolean;
|
|
27
|
+
closeButton?: boolean;
|
|
28
|
+
position?: ToastPosition;
|
|
29
|
+
/** Marks the toast for animated exit; toaster removes after exit. */
|
|
30
|
+
delete?: boolean;
|
|
31
|
+
};
|
|
32
|
+
export type ToastDismissDetail = {
|
|
33
|
+
id?: ToastId;
|
|
34
|
+
};
|
|
35
|
+
export type ToastShowDetail = Omit<ToastRecord, 'dismissible'> & {
|
|
36
|
+
dismissible?: boolean;
|
|
37
|
+
};
|
|
38
|
+
export type PromiseToastMessages<T> = {
|
|
39
|
+
loading: string;
|
|
40
|
+
success: string | ((data: T) => string);
|
|
41
|
+
error: string | ((error: unknown) => string);
|
|
42
|
+
description?: string | ((data: T | unknown) => string);
|
|
43
|
+
duration?: number;
|
|
44
|
+
action?: ToastAction;
|
|
45
|
+
closeButton?: boolean;
|
|
46
|
+
position?: ToastPosition;
|
|
47
|
+
};
|
|
48
|
+
export declare const TOAST_LIFETIME = 4000;
|
|
49
|
+
export declare const TOAST_WIDTH = 356;
|
|
50
|
+
export declare const TOAST_GAP = 14;
|
|
51
|
+
export declare const TOAST_VIEWPORT_OFFSET = 24;
|
|
52
|
+
export declare const TOAST_VISIBLE_AMOUNT = 3;
|
|
53
|
+
export declare const TOAST_SWIPE_THRESHOLD = 45;
|
|
54
|
+
export declare const TOAST_EXIT_MS = 200;
|
|
55
|
+
export declare const DEFAULT_TOAST_POSITION: ToastPosition;
|
|
56
|
+
export declare function splitToastPosition(position: ToastPosition): {
|
|
57
|
+
y: 'top' | 'bottom';
|
|
58
|
+
x: 'start' | 'center' | 'end';
|
|
59
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PromiseToastMessages, ToastId, ToastOptions, ToastRecord, ToastVariant } from './toast-context';
|
|
2
|
+
export type ToastSubscriber = (toasts: ToastRecord[]) => void;
|
|
3
|
+
declare class ToastState {
|
|
4
|
+
private subscribers;
|
|
5
|
+
private toasts;
|
|
6
|
+
subscribe: (subscriber: ToastSubscriber) => (() => void);
|
|
7
|
+
getSnapshot: () => ToastRecord[];
|
|
8
|
+
private publish;
|
|
9
|
+
create: (title: string, options?: ToastOptions & {
|
|
10
|
+
variant?: ToastVariant;
|
|
11
|
+
}) => ToastId;
|
|
12
|
+
dismiss: (id?: ToastId) => void;
|
|
13
|
+
remove: (id: ToastId) => void;
|
|
14
|
+
/** Drop every toast from the store (tests, Storybook resets). */
|
|
15
|
+
clear: () => void;
|
|
16
|
+
message: (title: string, options?: ToastOptions) => ToastId;
|
|
17
|
+
success: (title: string, options?: ToastOptions) => ToastId;
|
|
18
|
+
error: (title: string, options?: ToastOptions) => ToastId;
|
|
19
|
+
info: (title: string, options?: ToastOptions) => ToastId;
|
|
20
|
+
warning: (title: string, options?: ToastOptions) => ToastId;
|
|
21
|
+
loading: (title: string, options?: ToastOptions) => ToastId;
|
|
22
|
+
promise: <T>(promise: Promise<T> | (() => Promise<T>), messages: PromiseToastMessages<T>) => ToastId;
|
|
23
|
+
}
|
|
24
|
+
export declare const toastState: ToastState;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
@reference '../../../styles/radiant-ui.css';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Fixed toaster host. Stack transforms are written by JS onto `--y`
|
|
5
|
+
* (Sonner-style). CSS only handles enter/exit/swipe and chrome.
|
|
6
|
+
*/
|
|
7
|
+
rui-toaster {
|
|
8
|
+
position: fixed;
|
|
9
|
+
z-index: var(--z-toast, 50);
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
width: var(--width, 356px);
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
rui-toaster[data-y-position='top'] {
|
|
18
|
+
top: var(--viewport-offset, 24px);
|
|
19
|
+
bottom: auto;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
rui-toaster[data-y-position='bottom'] {
|
|
23
|
+
bottom: var(--viewport-offset, 24px);
|
|
24
|
+
top: auto;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
rui-toaster[data-x-position='end'] {
|
|
28
|
+
right: var(--viewport-offset, 24px);
|
|
29
|
+
left: auto;
|
|
30
|
+
transform: none;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
rui-toaster[data-x-position='start'] {
|
|
34
|
+
left: var(--viewport-offset, 24px);
|
|
35
|
+
right: auto;
|
|
36
|
+
transform: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
rui-toaster[data-x-position='center'] {
|
|
40
|
+
left: 50%;
|
|
41
|
+
right: auto;
|
|
42
|
+
transform: translateX(-50%);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
rui-toast {
|
|
46
|
+
--y: translateY(0);
|
|
47
|
+
--z-index: 1;
|
|
48
|
+
position: absolute;
|
|
49
|
+
left: 0;
|
|
50
|
+
width: 100%;
|
|
51
|
+
opacity: 0;
|
|
52
|
+
transform: var(--y);
|
|
53
|
+
touch-action: none;
|
|
54
|
+
box-sizing: border-box;
|
|
55
|
+
outline: none;
|
|
56
|
+
overflow-wrap: anywhere;
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
pointer-events: auto;
|
|
59
|
+
z-index: var(--z-index);
|
|
60
|
+
transition:
|
|
61
|
+
transform 400ms ease,
|
|
62
|
+
opacity 400ms ease,
|
|
63
|
+
height 400ms ease;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
rui-toaster[data-y-position='bottom'] rui-toast {
|
|
67
|
+
bottom: 0;
|
|
68
|
+
top: auto;
|
|
69
|
+
transform-origin: center bottom;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
rui-toaster[data-y-position='top'] rui-toast {
|
|
73
|
+
top: 0;
|
|
74
|
+
bottom: auto;
|
|
75
|
+
transform-origin: center top;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Enter from off-screen until JS mounts + patches --y */
|
|
79
|
+
rui-toast:not([data-mounted='true']) {
|
|
80
|
+
opacity: 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
rui-toaster[data-y-position='bottom'] rui-toast:not([data-mounted='true']) {
|
|
84
|
+
--y: translateY(100%);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
rui-toaster[data-y-position='top'] rui-toast:not([data-mounted='true']) {
|
|
88
|
+
--y: translateY(-100%);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
rui-toast[data-mounted='true'] {
|
|
92
|
+
opacity: 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
rui-toast[data-expanded='false'][data-front='false'] {
|
|
96
|
+
pointer-events: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
rui-toast[data-swiping='true'] {
|
|
100
|
+
transform: var(--y) translateY(var(--swipe-amount-y, 0px)) translateX(var(--swipe-amount-x, 0px));
|
|
101
|
+
transition: none;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
rui-toast[data-removed='true'][data-swipe-out='false'] {
|
|
105
|
+
opacity: 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
rui-toaster[data-y-position='bottom'] rui-toast[data-removed='true'][data-swipe-out='false'] {
|
|
109
|
+
--y: translateY(100%);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
rui-toaster[data-y-position='top'] rui-toast[data-removed='true'][data-swipe-out='false'] {
|
|
113
|
+
--y: translateY(-100%);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
rui-toast[data-swipe-out='true'] {
|
|
117
|
+
animation-duration: 200ms;
|
|
118
|
+
animation-timing-function: ease-out;
|
|
119
|
+
animation-fill-mode: forwards;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
rui-toast[data-swipe-out='true'][data-swipe-direction='left'] {
|
|
123
|
+
animation-name: rui-toast-swipe-out-left;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
rui-toast[data-swipe-out='true'][data-swipe-direction='right'] {
|
|
127
|
+
animation-name: rui-toast-swipe-out-right;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
rui-toast[data-swipe-out='true'][data-swipe-direction='up'] {
|
|
131
|
+
animation-name: rui-toast-swipe-out-up;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
rui-toast[data-swipe-out='true'][data-swipe-direction='down'] {
|
|
135
|
+
animation-name: rui-toast-swipe-out-down;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Hover bridge between expanded toasts */
|
|
139
|
+
rui-toast[data-expanded='true']::after {
|
|
140
|
+
content: '';
|
|
141
|
+
position: absolute;
|
|
142
|
+
left: 0;
|
|
143
|
+
width: 100%;
|
|
144
|
+
height: calc(var(--gap, 14px) + 1px);
|
|
145
|
+
bottom: 100%;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@layer components {
|
|
149
|
+
.rui-toaster-region {
|
|
150
|
+
display: contents;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.rui-toaster {
|
|
154
|
+
@apply relative m-0 list-none p-0;
|
|
155
|
+
width: 100%;
|
|
156
|
+
outline: none;
|
|
157
|
+
box-sizing: border-box;
|
|
158
|
+
pointer-events: auto;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
rui-toast .rui-toast > * {
|
|
162
|
+
transition: opacity 400ms ease;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
rui-toast[data-expanded='false'][data-front='false'] .rui-toast > * {
|
|
166
|
+
opacity: 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.rui-toast {
|
|
170
|
+
@apply relative flex w-full items-center gap-2 rounded-container border px-control-x py-control-y text-sm shadow-md rui-sheen;
|
|
171
|
+
@apply border-border bg-surface text-on-surface;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.rui-toast--info {
|
|
175
|
+
@apply border-border bg-surface text-on-surface;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.rui-toast--success {
|
|
179
|
+
@apply border-success/40 bg-surface text-success;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.rui-toast--warning {
|
|
183
|
+
@apply border-border bg-surface text-on-surface;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.rui-toast--error {
|
|
187
|
+
@apply border-error/40 bg-surface text-error;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.rui-toast--loading {
|
|
191
|
+
@apply border-border bg-surface text-on-surface;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.rui-toast__icon {
|
|
195
|
+
@apply inline-flex size-5 shrink-0 items-center justify-center text-sm font-semibold;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.rui-toast__loader {
|
|
199
|
+
@apply size-4 rounded-full border-2 border-current border-r-transparent;
|
|
200
|
+
animation: rui-toast-spin 0.7s linear infinite;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.rui-toast__content {
|
|
204
|
+
@apply flex min-w-0 flex-1 flex-col gap-0.5;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.rui-toast__title {
|
|
208
|
+
@apply font-medium leading-snug text-inherit;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.rui-toast__description {
|
|
212
|
+
@apply text-xs leading-snug opacity-80;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.rui-toast__action {
|
|
216
|
+
@apply shrink-0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.rui-toast__close {
|
|
220
|
+
@apply absolute -top-2 -left-2 inline-flex size-5 items-center justify-center rounded-full border border-border bg-surface text-xs text-on-surface;
|
|
221
|
+
@apply cursor-pointer leading-none;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.rui-toast__close:hover {
|
|
225
|
+
@apply bg-background;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.rui-toast__close:focus-visible {
|
|
229
|
+
@apply ring-2 ring-focus-ring outline-hidden;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
rui-toast:focus-visible .rui-toast {
|
|
233
|
+
@apply ring-2 ring-focus-ring;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@keyframes rui-toast-spin {
|
|
238
|
+
to {
|
|
239
|
+
transform: rotate(360deg);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
@keyframes rui-toast-swipe-out-left {
|
|
244
|
+
from {
|
|
245
|
+
transform: var(--y) translateX(var(--swipe-amount-x));
|
|
246
|
+
opacity: 1;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
to {
|
|
250
|
+
transform: var(--y) translateX(calc(var(--swipe-amount-x) - 100%));
|
|
251
|
+
opacity: 0;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@keyframes rui-toast-swipe-out-right {
|
|
256
|
+
from {
|
|
257
|
+
transform: var(--y) translateX(var(--swipe-amount-x));
|
|
258
|
+
opacity: 1;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
to {
|
|
262
|
+
transform: var(--y) translateX(calc(var(--swipe-amount-x) + 100%));
|
|
263
|
+
opacity: 0;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@keyframes rui-toast-swipe-out-up {
|
|
268
|
+
from {
|
|
269
|
+
transform: var(--y) translateY(var(--swipe-amount-y));
|
|
270
|
+
opacity: 1;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
to {
|
|
274
|
+
transform: var(--y) translateY(calc(var(--swipe-amount-y) - 100%));
|
|
275
|
+
opacity: 0;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@keyframes rui-toast-swipe-out-down {
|
|
280
|
+
from {
|
|
281
|
+
transform: var(--y) translateY(var(--swipe-amount-y));
|
|
282
|
+
opacity: 1;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
to {
|
|
286
|
+
transform: var(--y) translateY(calc(var(--swipe-amount-y) + 100%));
|
|
287
|
+
opacity: 0;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@media (max-width: 600px) {
|
|
292
|
+
rui-toaster {
|
|
293
|
+
left: var(--viewport-offset, 16px);
|
|
294
|
+
right: var(--viewport-offset, 16px);
|
|
295
|
+
width: auto;
|
|
296
|
+
transform: none;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
@media (prefers-reduced-motion: reduce) {
|
|
301
|
+
rui-toast,
|
|
302
|
+
.rui-toast__loader,
|
|
303
|
+
rui-toast .rui-toast > * {
|
|
304
|
+
transition: none !important;
|
|
305
|
+
animation: none !important;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
rui-toast[data-mounted='true'] {
|
|
309
|
+
opacity: 1;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
rui-toast[data-swipe-out='true'] {
|
|
313
|
+
opacity: 0;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithChildren, RadiantSlotProps } from '../../../types';
|
|
2
|
+
import type { RuiToastProps } from './toast.script';
|
|
3
|
+
import type { RuiToasterProps } from './toaster.script';
|
|
4
|
+
import './toast.css';
|
|
5
|
+
export type RuiToastViewProps = RuiToastProps & RadiantSlotProps;
|
|
6
|
+
export declare const RuiToast: import("../../../lib/radiant-view").RadiantViewComponent<RuiToastViewProps>;
|
|
7
|
+
export type RuiToasterViewProps = WithChildren<RuiToasterProps & RadiantSlotProps>;
|
|
8
|
+
export declare const RuiToaster: import("../../../lib/radiant-view").RadiantViewComponent<RuiToasterViewProps>;
|