better-toast 0.0.4 → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  import { NgComponentOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { signal, Injectable, inject, ElementRef, input, output, computed, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { signal, Injectable, inject, ElementRef, input, output, computed, afterNextRender, ChangeDetectionStrategy, Component, effect } from '@angular/core';
4
4
 
5
5
  /** Fallback when `<app-toaster [duration]>` is absent and a helper omits `durationMs`. */
6
6
  const DEFAULT_TOAST_DURATION_MS = 4000;
@@ -27,7 +27,8 @@ function shouldScheduleAutoDismiss(durationMs) {
27
27
  return Number.isFinite(durationMs) && durationMs > 0;
28
28
  }
29
29
  class ToasterService {
30
- _toasts = signal([], ...(ngDevMode ? [{ debugName: "_toasts" }] : /* istanbul ignore next */ []));
30
+ _toasts = signal([], /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "_toasts" }] : /* istanbul ignore next */ []));
31
32
  autoDismissByToastId = new Map();
32
33
  /** Updated by `<better-toaster [duration]>`; initial value is {@link DEFAULT_TOAST_DURATION_MS}. */
33
34
  defaultDurationMs = DEFAULT_TOAST_DURATION_MS;
@@ -395,10 +396,10 @@ class ToasterService {
395
396
  toast.onDismiss?.();
396
397
  }
397
398
  }
398
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ToasterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
399
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ToasterService, providedIn: 'root' });
399
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ToasterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
400
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ToasterService, providedIn: 'root' });
400
401
  }
401
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ToasterService, decorators: [{
402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ToasterService, decorators: [{
402
403
  type: Injectable,
403
404
  args: [{ providedIn: 'root' }]
404
405
  }] });
@@ -426,9 +427,31 @@ const TOAST_VARIANTS = [
426
427
  ];
427
428
 
428
429
  const GAP = 16;
430
+ /**
431
+ * Visible layers in the collapsed stack. Older toasts stay in the list and appear on hover.
432
+ * CSS hides the rest with `:nth-last-child(n + 4)` — keep that selector in sync.
433
+ */
434
+ const VISIBLE_TOASTS = 3;
429
435
  function swipeDirectionForPosition(position) {
430
436
  return position.startsWith('bottom') ? 'down' : 'up';
431
437
  }
438
+ /** True when the event target is a toast row (not the list itself, which can steal focus on dismiss). */
439
+ function isInsideToastItem(target) {
440
+ if (target instanceof Element) {
441
+ return target.closest('.toast') != null;
442
+ }
443
+ if (target instanceof Node && target.parentElement) {
444
+ return target.parentElement.closest('.toast') != null;
445
+ }
446
+ return false;
447
+ }
448
+ /**
449
+ * Touch and pen pointers do not hover. `pointerleave` fires on lift, which would collapse
450
+ * the stack before a second tap can reach a toast behind the front card.
451
+ */
452
+ function isNonHoverPointer(event) {
453
+ return event.pointerType === 'touch' || event.pointerType === 'pen';
454
+ }
432
455
  function resolveToasterOffsetSide(offset, side) {
433
456
  if (offset == null) {
434
457
  return undefined;
@@ -456,48 +479,82 @@ function mergeToastClassNames(base, override) {
456
479
  return base;
457
480
  return { ...base, ...override };
458
481
  }
482
+ /** Newest measured height in the stack. Skips the front toast until it has been measured. */
483
+ function resolveFrontToastHeightPx(toasts, heights) {
484
+ for (let i = toasts.length - 1; i >= 0; i--) {
485
+ const height = heights[toasts[i].id];
486
+ if (height) {
487
+ return height;
488
+ }
489
+ }
490
+ return undefined;
491
+ }
459
492
  class BetterToastItem {
460
493
  /** Shared toaster service (e.g. dismiss from the close button). */
461
494
  toaster = inject(ToasterService);
462
495
  /** Host element ref used to read `offsetHeight` after the first render. */
463
496
  host = inject(ElementRef);
464
497
  /** Toast payload (message, id, variant from the service). */
465
- toast = input(...(ngDevMode ? [undefined, { debugName: "toast" }] : /* istanbul ignore next */ []));
498
+ toast = input(/* @ts-ignore */
499
+ ...(ngDevMode ? [undefined, { debugName: "toast" }] : /* istanbul ignore next */ []));
466
500
  /**
467
501
  * Styles from `<app-toaster [toastOptions]>`; merged with {@link ToasterItem.style} so per-toast keys win.
468
502
  */
469
- toasterStyle = input(...(ngDevMode ? [undefined, { debugName: "toasterStyle" }] : /* istanbul ignore next */ []));
503
+ toasterStyle = input(/* @ts-ignore */
504
+ ...(ngDevMode ? [undefined, { debugName: "toasterStyle" }] : /* istanbul ignore next */ []));
470
505
  /**
471
506
  * Classes from `<app-toaster [toastOptions]>` — same shape as {@link ToasterToastOptions.classNames}.
472
507
  * Merged with {@link ToasterItem.classNames}; per-toast keys replace the same keys from the toaster.
473
508
  * Styles for those classes usually need **`!important`** to override the library’s encapsulated CSS; see {@link ToastChromeClassNames}.
474
509
  */
475
- toasterClassNames = input(...(ngDevMode ? [undefined, { debugName: "toasterClassNames" }] : /* istanbul ignore next */ []));
510
+ toasterClassNames = input(/* @ts-ignore */
511
+ ...(ngDevMode ? [undefined, { debugName: "toasterClassNames" }] : /* istanbul ignore next */ []));
476
512
  /** Which icon and color treatment to show for this row. */
477
- variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
478
- /** Vertical stack offset in px; bound to `--offset` on the host for layout. */
479
- offset = input.required(...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
513
+ variant = input('default', /* @ts-ignore */
514
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
480
515
  /** When false, the dismiss control is not rendered (toasts may still auto-dismiss or be cleared via the service). */
481
- closeButton = input(true, ...(ngDevMode ? [{ debugName: "closeButton" }] : /* istanbul ignore next */ []));
516
+ closeButton = input(true, /* @ts-ignore */
517
+ ...(ngDevMode ? [{ debugName: "closeButton" }] : /* istanbul ignore next */ []));
482
518
  /**
483
519
  * Per-variant icon overrides from `<app-toaster [icons]>`.
484
520
  * Each override must be a standalone component whose template includes the SVG artwork.
485
521
  */
486
- customIcons = input(...(ngDevMode ? [undefined, { debugName: "customIcons" }] : /* istanbul ignore next */ []));
522
+ customIcons = input(/* @ts-ignore */
523
+ ...(ngDevMode ? [undefined, { debugName: "customIcons" }] : /* istanbul ignore next */ []));
487
524
  /**
488
525
  * `aria-label` for the dismiss control; set from `<better-toaster [accessibilityLabels]>`.
489
526
  * Default {@link DEFAULT_TOASTER_ARIA_DISMISS_BUTTON}.
490
527
  */
491
- dismissButtonAriaLabel = input(DEFAULT_TOASTER_ARIA_DISMISS_BUTTON, ...(ngDevMode ? [{ debugName: "dismissButtonAriaLabel" }] : /* istanbul ignore next */ []));
528
+ dismissButtonAriaLabel = input(DEFAULT_TOASTER_ARIA_DISMISS_BUTTON, /* @ts-ignore */
529
+ ...(ngDevMode ? [{ debugName: "dismissButtonAriaLabel" }] : /* istanbul ignore next */ []));
492
530
  /** Stack anchor from `<better-toaster [position]>` — drives swipe axis and `data-swipe-direction`. */
493
- stackPosition = input('bottom-right', ...(ngDevMode ? [{ debugName: "stackPosition" }] : /* istanbul ignore next */ []));
531
+ stackPosition = input('bottom-right', /* @ts-ignore */
532
+ ...(ngDevMode ? [{ debugName: "stackPosition" }] : /* istanbul ignore next */ []));
533
+ /** True while the stack is hovered or focus is inside it (expanded layout). */
534
+ stackExpanded = input(false, /* @ts-ignore */
535
+ ...(ngDevMode ? [{ debugName: "stackExpanded" }] : /* istanbul ignore next */ []));
536
+ /** True when this toast is the newest (front) layer in the stack. */
537
+ stackFront = input(false, /* @ts-ignore */
538
+ ...(ngDevMode ? [{ debugName: "stackFront" }] : /* istanbul ignore next */ []));
539
+ /** Tells the parent whether the pointer is still over the toast stack. */
540
+ stackHover = output();
494
541
  /**
495
542
  * Color palette from `<better-toaster [theme]>`; mirrored on the host as `data-theme`
496
543
  * so item-scoped CSS can react to the chosen mode without `:host-context()`.
497
544
  */
498
- theme = input('system', ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
545
+ theme = input('system', /* @ts-ignore */
546
+ ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
499
547
  /** Emits the measured host height in px once after the first render so the parent can stack siblings. */
500
548
  heightChange = output();
549
+ /** Natural host height in px, captured once after first paint (used to restore height on expand). */
550
+ initialHeight = signal(undefined, /* @ts-ignore */
551
+ ...(ngDevMode ? [{ debugName: "initialHeight" }] : /* istanbul ignore next */ []));
552
+ /** Bound as `--initial-height` so collapsed layers can return to their own size. */
553
+ initialHeightCss = computed(() => {
554
+ const height = this.initialHeight();
555
+ return height ? `${height}px` : null;
556
+ }, /* @ts-ignore */
557
+ ...(ngDevMode ? [{ debugName: "initialHeightCss" }] : /* istanbul ignore next */ []));
501
558
  /**
502
559
  * Stacked title + optional secondary line: {@link ToastVariant} **`description`**, or any variant with
503
560
  * non-empty {@link ToasterItem.description} ({@link ToastOptions.description} on `show` / `success` / etc.).
@@ -509,11 +566,14 @@ class BetterToastItem {
509
566
  if (toast.variant === 'description')
510
567
  return true;
511
568
  return !!toast.description?.trim();
512
- }, ...(ngDevMode ? [{ debugName: "hasDescription" }] : /* istanbul ignore next */ []));
569
+ }, /* @ts-ignore */
570
+ ...(ngDevMode ? [{ debugName: "hasDescription" }] : /* istanbul ignore next */ []));
513
571
  /** Merged inline styles for the toast (`[toastOptions].style` then per-toast `style`). */
514
- hostStyle = computed(() => mergeToastHostStyles(this.toasterStyle(), this.toast()?.style), ...(ngDevMode ? [{ debugName: "hostStyle" }] : /* istanbul ignore next */ []));
572
+ hostStyle = computed(() => mergeToastHostStyles(this.toasterStyle(), this.toast()?.style), /* @ts-ignore */
573
+ ...(ngDevMode ? [{ debugName: "hostStyle" }] : /* istanbul ignore next */ []));
515
574
  /** Merged `[class]` strings (`[toastOptions].classNames` then per-toast `classNames`). */
516
- resolvedClassNames = computed(() => mergeToastClassNames(this.toasterClassNames(), this.toast()?.classNames), ...(ngDevMode ? [{ debugName: "resolvedClassNames" }] : /* istanbul ignore next */ []));
575
+ resolvedClassNames = computed(() => mergeToastClassNames(this.toasterClassNames(), this.toast()?.classNames), /* @ts-ignore */
576
+ ...(ngDevMode ? [{ debugName: "resolvedClassNames" }] : /* istanbul ignore next */ []));
517
577
  /** Resolved standalone SVG icon component from `[icons]`, if any (not `null`). */
518
578
  iconComponent = computed(() => {
519
579
  const customIcon = this.customIcons()?.[this.variant()];
@@ -521,7 +581,8 @@ class BetterToastItem {
521
581
  return undefined;
522
582
  }
523
583
  return customIcon;
524
- }, ...(ngDevMode ? [{ debugName: "iconComponent" }] : /* istanbul ignore next */ []));
584
+ }, /* @ts-ignore */
585
+ ...(ngDevMode ? [{ debugName: "iconComponent" }] : /* istanbul ignore next */ []));
525
586
  /**
526
587
  * Renders the icon column unless the toast or `[icons]` opts out with `icon: null` / a `null` entry for that variant.
527
588
  * The `default` variant has no built-in icon: the column appears only with a per-toast `icon` or `[icons].default`.
@@ -552,26 +613,45 @@ class BetterToastItem {
552
613
  return false;
553
614
  }
554
615
  return true;
555
- }, ...(ngDevMode ? [{ debugName: "shouldShowIconColumn" }] : /* istanbul ignore next */ []));
616
+ }, /* @ts-ignore */
617
+ ...(ngDevMode ? [{ debugName: "shouldShowIconColumn" }] : /* istanbul ignore next */ []));
556
618
  /** Bound to {@link ToasterItem.componentInputs} for headless (`NgComponentOutlet`) toasts. */
557
- componentOutletInputs = computed(() => this.toast()?.componentInputs ?? {}, ...(ngDevMode ? [{ debugName: "componentOutletInputs" }] : /* istanbul ignore next */ []));
619
+ componentOutletInputs = computed(() => this.toast()?.componentInputs ?? {}, /* @ts-ignore */
620
+ ...(ngDevMode ? [{ debugName: "componentOutletInputs" }] : /* istanbul ignore next */ []));
558
621
  /** Bound to {@link ToasterItem.contentComponentInputs} for {@link ToasterService.custom} body components. */
559
- contentComponentOutletInputs = computed(() => this.toast()?.contentComponentInputs ?? {}, ...(ngDevMode ? [{ debugName: "contentComponentOutletInputs" }] : /* istanbul ignore next */ []));
622
+ contentComponentOutletInputs = computed(() => this.toast()?.contentComponentInputs ?? {}, /* @ts-ignore */
623
+ ...(ngDevMode ? [{ debugName: "contentComponentOutletInputs" }] : /* istanbul ignore next */ []));
560
624
  /** When true, host uses no default toast chrome (border, padding, surface) — only stack + motion. */
561
- isHeadless = computed(() => this.toast()?.component != null, ...(ngDevMode ? [{ debugName: "isHeadless" }] : /* istanbul ignore next */ []));
625
+ isHeadless = computed(() => this.toast()?.component != null, /* @ts-ignore */
626
+ ...(ngDevMode ? [{ debugName: "isHeadless" }] : /* istanbul ignore next */ []));
627
+ /**
628
+ * Dismiss control stays on the front toast. Stacked toasts mount it only while the stack is
629
+ * expanded so `animate.enter` / `animate.leave` can run without moving the front control.
630
+ */
631
+ showCloseButton = computed(() => this.closeButton() && !this.isHeadless() && (this.stackFront() || this.stackExpanded()), /* @ts-ignore */
632
+ ...(ngDevMode ? [{ debugName: "showCloseButton" }] : /* istanbul ignore next */ []));
633
+ /** Enter class for stacked close buttons; the front control does not animate in. */
634
+ closeButtonEnterClass = computed(() => this.stackFront() ? null : 'close-enter', /* @ts-ignore */
635
+ ...(ngDevMode ? [{ debugName: "closeButtonEnterClass" }] : /* istanbul ignore next */ []));
636
+ /** Leave class for stacked close buttons; the front control does not animate out. */
637
+ closeButtonLeaveClass = computed(() => this.stackFront() ? null : 'close-leave', /* @ts-ignore */
638
+ ...(ngDevMode ? [{ debugName: "closeButtonLeaveClass" }] : /* istanbul ignore next */ []));
562
639
  /** `down` when anchored to the bottom (dismiss by swiping down), `up` when anchored to the top. */
563
- swipeDirection = computed(() => swipeDirectionForPosition(this.stackPosition()), ...(ngDevMode ? [{ debugName: "swipeDirection" }] : /* istanbul ignore next */ []));
640
+ swipeDirection = computed(() => swipeDirectionForPosition(this.stackPosition()), /* @ts-ignore */
641
+ ...(ngDevMode ? [{ debugName: "swipeDirection" }] : /* istanbul ignore next */ []));
564
642
  /**
565
643
  * Emits the measured host height in px once after the first render so the parent can stack siblings.
566
644
  */
567
645
  constructor() {
568
646
  afterNextRender(() => {
569
647
  const height = this.host.nativeElement.offsetHeight;
648
+ this.initialHeight.set(height);
570
649
  this.heightChange.emit(height);
571
650
  });
572
651
  }
573
652
  /** True once the user has passed the drag threshold and is actively swiping. */
574
- isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
653
+ isDragging = signal(false, /* @ts-ignore */
654
+ ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
575
655
  tracking = false;
576
656
  startY = 0;
577
657
  pointerId = -1;
@@ -586,7 +666,8 @@ class BetterToastItem {
586
666
  return `translateX(-50%) translateY(${y})`;
587
667
  }
588
668
  return `translateY(${y})`;
589
- }, ...(ngDevMode ? [{ debugName: "swipeDismissTransform" }] : /* istanbul ignore next */ []));
669
+ }, /* @ts-ignore */
670
+ ...(ngDevMode ? [{ debugName: "swipeDismissTransform" }] : /* istanbul ignore next */ []));
590
671
  /** Prevents swipe-to-dismiss from starting when pressing the row action / cancel control. */
591
672
  onRowButtonPointerDown(event) {
592
673
  event.stopPropagation();
@@ -606,15 +687,26 @@ class BetterToastItem {
606
687
  * Pauses auto-dismiss when the pointer enters the toast.
607
688
  */
608
689
  onPointerEnter() {
690
+ this.stackHover.emit(true);
609
691
  const id = this.toast()?.id;
610
692
  if (id) {
611
693
  this.toaster.pauseAutoDismiss(id);
612
694
  }
613
695
  }
614
696
  /**
615
- * Resumes auto-dismiss when the pointer leaves the toast.
697
+ * Resumes auto-dismiss when a hover pointer leaves the toast stack.
698
+ * Moving onto a sibling toast keeps the stack expanded.
699
+ * Touch/pen leave is ignored: the stack stays expanded until a tap outside.
616
700
  */
617
- onPointerLeave() {
701
+ onPointerLeave(event) {
702
+ if (isNonHoverPointer(event)) {
703
+ return;
704
+ }
705
+ const stillInStack = isInsideToastItem(event.relatedTarget);
706
+ this.stackHover.emit(stillInStack);
707
+ if (stillInStack || this.stackExpanded()) {
708
+ return;
709
+ }
618
710
  const id = this.toast()?.id;
619
711
  if (id) {
620
712
  this.toaster.resumeAutoDismiss(id);
@@ -710,189 +802,191 @@ class BetterToastItem {
710
802
  /* pointer already released */
711
803
  }
712
804
  }
713
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BetterToastItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
714
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BetterToastItem, isStandalone: true, selector: "li[betterToastItem]", inputs: { toast: { classPropertyName: "toast", publicName: "toast", isSignal: true, isRequired: false, transformFunction: null }, toasterStyle: { classPropertyName: "toasterStyle", publicName: "toasterStyle", isSignal: true, isRequired: false, transformFunction: null }, toasterClassNames: { classPropertyName: "toasterClassNames", publicName: "toasterClassNames", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: true, transformFunction: null }, closeButton: { classPropertyName: "closeButton", publicName: "closeButton", isSignal: true, isRequired: false, transformFunction: null }, customIcons: { classPropertyName: "customIcons", publicName: "customIcons", isSignal: true, isRequired: false, transformFunction: null }, dismissButtonAriaLabel: { classPropertyName: "dismissButtonAriaLabel", publicName: "dismissButtonAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, stackPosition: { classPropertyName: "stackPosition", publicName: "stackPosition", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { heightChange: "heightChange" }, host: { attributes: { "role": "listitem", "tabindex": "0" }, listeners: { "pointerdown": "onPointerDown($event)", "pointermove": "onPointerMove($event)", "pointerup": "onPointerUp()", "pointercancel": "onPointerCancel()", "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave()" }, properties: { "class": "resolvedClassNames()?.toast", "attr.data-variant": "variant()", "attr.data-icon": "shouldShowIconColumn() ? \"true\" : \"false\"", "attr.data-headless": "isHeadless() ? \"true\" : null", "attr.data-swipe-direction": "swipeDirection()", "attr.data-theme": "theme()", "style.--offset": "offset() + \"px\"", "style": "isHeadless() ? undefined : hostStyle()", "animate.leave": "\"leave\"" }, classAttribute: "toast" }, ngImport: i0, template: `
715
- @if (toast()?.component) {
716
- <ng-container *ngComponentOutlet="toast()!.component!; inputs: componentOutletInputs()" />
717
- } @else {
718
- @if (shouldShowIconColumn()) {
719
- <span class="toast-icon" aria-hidden="true">
720
- @if (toast()?.icon) {
721
- <ng-container *ngComponentOutlet="toast()!.icon!" />
722
- } @else if (iconComponent(); as IconCmp) {
723
- <ng-container *ngComponentOutlet="IconCmp" />
724
- } @else {
725
- @switch (variant()) {
726
- @case ('success') {
727
- <svg
728
- xmlns="http://www.w3.org/2000/svg"
729
- fill="none"
730
- viewBox="0 0 24 24"
731
- aria-hidden="true"
732
- >
733
- <circle
734
- cx="12"
735
- cy="12"
736
- r="9"
737
- stroke="currentColor"
738
- stroke-linecap="round"
739
- stroke-linejoin="round"
740
- stroke-width="1.75"
741
- />
742
- <path
743
- stroke="currentColor"
744
- stroke-linecap="round"
745
- stroke-linejoin="round"
746
- stroke-width="1.75"
747
- d="M8.48 12.22 10.9 14.64 15.74 9.14"
748
- />
749
- </svg>
750
- }
751
- @case ('error') {
752
- <svg
753
- aria-hidden="true"
754
- xmlns="http://www.w3.org/2000/svg"
755
- viewBox="0 0 24 24"
756
- fill="none"
757
- stroke="currentColor"
758
- stroke-width="2"
759
- stroke-linecap="round"
760
- stroke-linejoin="round"
761
- >
762
- <circle cx="12" cy="12" r="10" />
763
- <line x1="9" y1="9" x2="15" y2="15" />
764
- <line x1="15" y1="9" x2="9" y2="15" />
765
- </svg>
766
- }
767
- @case ('info') {
768
- <svg
769
- aria-hidden="true"
770
- xmlns="http://www.w3.org/2000/svg"
771
- viewBox="0 0 24 24"
772
- fill="none"
773
- stroke="currentColor"
774
- stroke-width="1.75"
775
- stroke-linecap="round"
776
- stroke-linejoin="round"
777
- >
778
- <circle cx="12" cy="12" r="10" />
779
- <line x1="12" y1="16" x2="12" y2="12" />
780
- <line x1="12" y1="8" x2="12.01" y2="8" />
781
- </svg>
782
- }
783
- @case ('warning') {
784
- <svg
785
- aria-hidden="true"
786
- xmlns="http://www.w3.org/2000/svg"
787
- fill="none"
788
- viewBox="0 0 24 24"
789
- >
790
- <path
791
- stroke="currentColor"
792
- stroke-linecap="round"
793
- stroke-linejoin="round"
794
- stroke-width="1.75"
795
- d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"
796
- />
797
- </svg>
798
- }
799
- @case ('loading') {
800
- <div class="toast-icon-loading" aria-hidden="true"></div>
801
- }
802
- @case ('description') {}
803
- @case ('default') {}
804
- }
805
- }
806
- </span>
807
- }
808
-
809
- @if (hasDescription()) {
810
- <div class="stack">
811
- @if (toast()?.contentComponent) {
812
- <div class="msg" [class]="resolvedClassNames()?.message">
813
- <ng-container
814
- *ngComponentOutlet="
815
- toast()!.contentComponent!;
816
- inputs: contentComponentOutletInputs()
817
- "
818
- />
819
- </div>
820
- } @else {
821
- <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
822
- }
823
- @if (toast()?.description) {
824
- <p class="description" [class]="resolvedClassNames()?.description">
825
- {{ toast()!.description }}
826
- </p>
827
- }
828
- </div>
829
- } @else {
830
- @if (toast()?.contentComponent) {
831
- <div class="msg" [class]="resolvedClassNames()?.message">
832
- <ng-container
833
- *ngComponentOutlet="
834
- toast()!.contentComponent!;
835
- inputs: contentComponentOutletInputs()
836
- "
837
- />
838
- </div>
839
- } @else {
840
- <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
841
- }
842
- }
843
-
844
- @if (toast()?.toastAction; as rowAction) {
845
- @switch (rowAction.role) {
846
- @case ('action') {
847
- <button
848
- type="button"
849
- class="toast-row-btn action-btn"
850
- [class]="resolvedClassNames()?.actionButton"
851
- [attr.data-row-btn]="rowAction.role"
852
- (pointerdown)="onRowButtonPointerDown($event)"
853
- (click)="onToastRowClick($event)"
854
- >
855
- {{ rowAction.label }}
856
- </button>
857
- }
858
- @case ('cancel') {
859
- <button
860
- type="button"
861
- class="toast-row-btn cancel-btn"
862
- [class]="resolvedClassNames()?.cancelButton"
863
- [attr.data-row-btn]="rowAction.role"
864
- (pointerdown)="onRowButtonPointerDown($event)"
865
- (click)="onToastRowClick($event)"
866
- >
867
- {{ rowAction.label }}
868
- </button>
869
- }
870
- }
871
- }
872
- }
873
-
874
- @if (closeButton() && !isHeadless()) {
875
- <button
876
- type="button"
877
- class="close-btn"
878
- [class]="resolvedClassNames()?.closeButton"
879
- (click)="toaster.dismiss(toast()?.id ?? '')"
880
- [attr.aria-label]="dismissButtonAriaLabel()"
881
- >
882
- <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
883
- <path
884
- stroke="currentColor"
885
- stroke-linecap="round"
886
- stroke-linejoin="round"
887
- stroke-width="1.75"
888
- d="M6 18 18 6M6 6l12 12"
889
- />
890
- </svg>
891
- </button>
892
- }
893
- `, isInline: true, styles: [":host{display:flex;align-items:center;gap:.375rem;flex:1;min-width:0;width:100%;padding-inline:.75rem;padding-block:1rem;box-sizing:border-box;border:1px solid var(--toast-border-color);border-radius:.5rem;box-shadow:var(--toast-shadow);background:var(--toast-bg);color:var(--toast-color);--toast-line-height: 1.35;font:500 .875rem/var(--toast-line-height) system-ui,sans-serif;pointer-events:auto;touch-action:none;-webkit-user-select:none;user-select:none;position:absolute;opacity:1;scale:1;transition:opacity .4s ease,transform .4s ease,scale .4s ease,box-shadow .2s ease}:host([data-variant=\"loading\"]){touch-action:auto}@media(width>=40rem){:host{width:var(--toast-width)}}:host([data-position^=\"bottom\"]){bottom:0;transform:translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-position^=\"bottom\"]){opacity:0;transform:translateY(100%)}}:host([data-position^=\"top\"]){top:0;transform:translateY(calc(1 * var(--offset, 0px)))}@starting-style{:host([data-position^=\"top\"]){opacity:0;transform:translateY(-100%)}}@starting-style{:host([data-headless=\"true\"][data-position^=\"bottom\"]){opacity:1}}@starting-style{:host([data-headless=\"true\"][data-position^=\"top\"]){opacity:1}}:host([data-variant=\"default\"]) .toast-icon svg,:host([data-variant=\"default\"]) .toast-icon ::ng-deep svg,:host([data-variant=\"description\"]) .toast-icon svg,:host([data-variant=\"description\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"success\"]){background:var(--toast-success-bg);color:var(--toast-success-text);border-color:var(--toast-success-border)}:host([data-rich-colors=\"false\"][data-variant=\"success\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"success\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"success\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"success\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-success-text),var(--toast-success-bg));stroke:light-dark(var(--toast-success-bg),var(--toast-success-text));color:light-dark(var(--toast-success-bg),var(--toast-success-text))}:host([data-rich-colors=\"true\"][data-variant=\"error\"]){background:var(--toast-error-bg);color:var(--toast-error-text);border-color:var(--toast-error-border)}:host([data-rich-colors=\"false\"][data-variant=\"error\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"error\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"error\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"error\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-error-text),var(--toast-error-bg));stroke:light-dark(var(--toast-error-bg),var(--toast-error-text));color:light-dark(var(--toast-error-bg),var(--toast-error-text))}:host([data-rich-colors=\"true\"][data-variant=\"info\"]){background:var(--toast-info-bg);color:var(--toast-info-text);border-color:var(--toast-info-border)}:host([data-rich-colors=\"false\"][data-variant=\"info\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"info\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"info\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"info\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-info-text),var(--toast-info-bg));stroke:light-dark(var(--toast-info-bg),var(--toast-info-text));color:light-dark(var(--toast-info-bg),var(--toast-info-text))}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]){background:var(--toast-warning-bg);color:var(--toast-warning-text);border-color:var(--toast-warning-border)}:host([data-rich-colors=\"false\"][data-variant=\"warning\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"warning\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"warning\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-warning-text),var(--toast-warning-bg));stroke:light-dark(var(--toast-warning-bg),var(--toast-warning-text));color:light-dark(var(--toast-warning-bg),var(--toast-warning-text))}:host([data-headless=\"true\"]){width:max-content;max-width:calc(100dvw - var(--toast-offset-mobile-left, 16px) - var(--toast-offset-mobile-right, 16px));padding:0;gap:0;border:none;border-radius:0;box-shadow:none;background:transparent;color:inherit;font:inherit;line-height:normal;--toast-line-height: inherit}@media(width>=40rem){:host([data-headless=\"true\"]){max-width:calc(100dvw - var(--toast-offset-left, 24px) - var(--toast-offset-right, 24px))}}@media(width>=40rem){:host([data-headless=\"true\"][data-position$=\"-right\"]){left:auto;right:0}:host([data-headless=\"true\"][data-position$=\"-left\"]){left:0;right:auto}}:host([data-headless=\"true\"][data-position=\"bottom-center\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position=\"bottom-center\"]){opacity:1;transform:translate(-50%) translateY(100%)}}:host([data-headless=\"true\"][data-position=\"top-center\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position=\"top-center\"]){opacity:1;transform:translate(-50%) translateY(-100%)}}@media(width<40rem){:host([data-headless=\"true\"][data-position^=\"bottom\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position^=\"bottom\"]){opacity:1;transform:translate(-50%) translateY(100%)}}:host([data-headless=\"true\"][data-position^=\"top\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position^=\"top\"]){opacity:1;transform:translate(-50%) translateY(-100%)}}:host([data-headless=\"true\"][data-swipe-direction=\"down\"].leave){transform:translate(-50%) translateY(100%)}:host([data-headless=\"true\"][data-swipe-direction=\"up\"].leave){transform:translate(-50%) translateY(-100%)}}:host([data-headless=\"true\"][data-rich-colors=\"true\"]){background:transparent;color:inherit;border-color:transparent}:host([data-headless=\"true\"][data-icon=\"false\"]){padding-left:0}:host([data-icon=\"false\"]){padding-left:.925rem}.toast-icon,.toast-icon ::ng-deep{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.425rem;height:1.425rem}.toast-icon svg,.toast-icon ::ng-deep svg{display:block;margin-inline:auto;fill:light-dark(var(--toast-color),var(--toast-bg));stroke:light-dark(var(--toast-bg),var(--toast-color));width:95%;height:95%}:host([data-theme=\"dark\"]) .toast-icon svg,:host([data-theme=\"dark\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}@media(prefers-color-scheme:dark){:host([data-theme=\"system\"]) .toast-icon svg,:host([data-theme=\"system\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}}.toast-icon-loading{display:block;width:.9rem;height:.9rem;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;border-right-color:transparent;animation:spin .45s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.msg{flex:1;min-width:0;max-width:95%;margin:0;font-size:.825rem;font-weight:500;line-height:calc(1.25 / .875);letter-spacing:.01em}@media(width<40rem){.msg{max-width:90%;font-size:.8rem}}.stack{display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;flex:1;min-width:0}.stack .msg{flex:0 1 auto;max-width:100%}:host([data-icon=\"false\"]) .stack .msg{max-width:90%}.description{margin:0;font-size:.825rem;font-weight:400;line-height:1.35;letter-spacing:.01em;opacity:.9;max-width:100%}@media(width<40rem){.description{font-size:.8rem}}.toast-row-btn{flex-shrink:0;margin:0;margin-inline-start:auto;padding:.35rem .65rem;border-radius:.375rem;border:1px solid transparent;font:inherit;font-size:.8rem;font-weight:600;letter-spacing:.01em;line-height:1.2;cursor:pointer;white-space:nowrap;transition:transform .2s ease}.toast-row-btn:focus-visible{outline:2px solid var(--toast-color);outline-offset:2px}.toast-row-btn:active{transform:scale(.95)}@media(prefers-reduced-motion:reduce){.toast-row-btn:active{transform:none}}.action-btn{background:var(--toast-action-bg);color:var(--toast-action-text);border-color:var(--toast-action-border)}.cancel-btn{background:var(--toast-cancel-bg);color:var(--toast-color);border-color:var(--toast-cancel-border)}.toast-custom{flex:1;min-width:0;width:100%;font-size:.825rem;font-weight:400;line-height:calc(1.25 / .875)}.toast-custom :first-child{margin-top:0}.toast-custom :last-child{margin-bottom:0}.close-btn{position:absolute;top:-.3875rem;right:-.3875rem;flex-shrink:0;margin:-.15rem -.25rem -.15rem 0;border:1px solid var(--toast-border-color);box-shadow:var(--toast-shadow);background:var(--toast-bg);color:var(--toast-color);cursor:pointer;line-height:1;padding:.25rem;border-radius:50%;display:inline-flex;align-items:center;justify-content:center}:host([data-rich-colors=\"true\"][data-variant=\"success\"]) .close-btn{border-color:var(--toast-success-border);background:var(--toast-success-bg);color:var(--toast-success-text)}:host([data-rich-colors=\"true\"][data-variant=\"error\"]) .close-btn{border-color:var(--toast-error-border);background:var(--toast-error-bg);color:var(--toast-error-text)}:host([data-rich-colors=\"true\"][data-variant=\"info\"]) .close-btn{border-color:var(--toast-info-border);background:var(--toast-info-bg);color:var(--toast-info-text)}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]) .close-btn{border-color:var(--toast-warning-border);background:var(--toast-warning-bg);color:var(--toast-warning-text)}.close-btn:focus-visible{outline:2px solid currentColor}.close-btn svg{display:block;width:.825rem;height:.825rem}:host(.leave){opacity:0;scale:.95}:host([data-swipe-direction=\"down\"].leave){transform:translateY(100%)}:host([data-headless=\"true\"][data-position=\"bottom-center\"].leave){transform:translate(-50%) translateY(100%)}:host([data-swipe-direction=\"up\"].leave){transform:translateY(-100%)}:host([data-headless=\"true\"][data-position=\"top-center\"].leave){transform:translate(-50%) translateY(-100%)}@media(prefers-reduced-motion:reduce){:host{transition:none}:host(.leave){scale:1}@starting-style{:host([data-position^=\"bottom\"]){opacity:0;transform:translateY(calc(-1 * var(--offset, 0px)))}}@starting-style{:host([data-position^=\"top\"]){opacity:0;transform:translateY(calc(1 * var(--offset, 0px)))}}@starting-style{:host([data-headless=\"true\"][data-position=\"bottom-center\"]){opacity:1;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}}@starting-style{:host([data-headless=\"true\"][data-position=\"top-center\"]){opacity:1;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}}:host([data-swipe-direction=\"down\"].leave){transform:translateY(calc(-1 * var(--offset, 0px)))}:host([data-swipe-direction=\"up\"].leave){transform:translateY(calc(1 * var(--offset, 0px)))}:host([data-headless=\"true\"][data-position=\"bottom-center\"].leave){transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}:host([data-headless=\"true\"][data-position=\"top-center\"].leave){transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}@media(width<40rem){@starting-style{:host([data-headless=\"true\"][data-position^=\"bottom\"]){opacity:1;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}}:host([data-headless=\"true\"][data-swipe-direction=\"down\"].leave){transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position^=\"top\"]){opacity:1;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}}:host([data-headless=\"true\"][data-swipe-direction=\"up\"].leave){transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}}.toast-icon-loading{animation:none}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
805
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: BetterToastItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
806
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: BetterToastItem, isStandalone: true, selector: "li[betterToastItem]", inputs: { toast: { classPropertyName: "toast", publicName: "toast", isSignal: true, isRequired: false, transformFunction: null }, toasterStyle: { classPropertyName: "toasterStyle", publicName: "toasterStyle", isSignal: true, isRequired: false, transformFunction: null }, toasterClassNames: { classPropertyName: "toasterClassNames", publicName: "toasterClassNames", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, closeButton: { classPropertyName: "closeButton", publicName: "closeButton", isSignal: true, isRequired: false, transformFunction: null }, customIcons: { classPropertyName: "customIcons", publicName: "customIcons", isSignal: true, isRequired: false, transformFunction: null }, dismissButtonAriaLabel: { classPropertyName: "dismissButtonAriaLabel", publicName: "dismissButtonAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, stackPosition: { classPropertyName: "stackPosition", publicName: "stackPosition", isSignal: true, isRequired: false, transformFunction: null }, stackExpanded: { classPropertyName: "stackExpanded", publicName: "stackExpanded", isSignal: true, isRequired: false, transformFunction: null }, stackFront: { classPropertyName: "stackFront", publicName: "stackFront", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stackHover: "stackHover", heightChange: "heightChange" }, host: { attributes: { "role": "listitem", "tabindex": "0" }, listeners: { "pointerdown": "onPointerDown($event)", "pointermove": "onPointerMove($event)", "pointerup": "onPointerUp()", "pointercancel": "onPointerCancel()", "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave($event)" }, properties: { "class": "resolvedClassNames()?.toast", "attr.data-variant": "variant()", "attr.data-icon": "shouldShowIconColumn() ? \"true\" : \"false\"", "attr.data-headless": "isHeadless() ? \"true\" : null", "attr.data-swipe-direction": "swipeDirection()", "attr.data-theme": "theme()", "style.--initial-height": "initialHeightCss()", "style": "isHeadless() ? undefined : hostStyle()", "animate.leave": "\"leave\"" }, classAttribute: "toast" }, ngImport: i0, template: `
807
+ @if (toast()?.component) {
808
+ <ng-container *ngComponentOutlet="toast()!.component!; inputs: componentOutletInputs()" />
809
+ } @else {
810
+ @if (shouldShowIconColumn()) {
811
+ <span class="toast-icon" aria-hidden="true">
812
+ @if (toast()?.icon) {
813
+ <ng-container *ngComponentOutlet="toast()!.icon!" />
814
+ } @else if (iconComponent(); as IconCmp) {
815
+ <ng-container *ngComponentOutlet="IconCmp" />
816
+ } @else {
817
+ @switch (variant()) {
818
+ @case ('success') {
819
+ <svg
820
+ xmlns="http://www.w3.org/2000/svg"
821
+ fill="none"
822
+ viewBox="0 0 24 24"
823
+ aria-hidden="true"
824
+ >
825
+ <circle
826
+ cx="12"
827
+ cy="12"
828
+ r="9"
829
+ stroke="currentColor"
830
+ stroke-linecap="round"
831
+ stroke-linejoin="round"
832
+ stroke-width="1.75"
833
+ />
834
+ <path
835
+ stroke="currentColor"
836
+ stroke-linecap="round"
837
+ stroke-linejoin="round"
838
+ stroke-width="1.75"
839
+ d="M8.48 12.22 10.9 14.64 15.74 9.14"
840
+ />
841
+ </svg>
842
+ }
843
+ @case ('error') {
844
+ <svg
845
+ aria-hidden="true"
846
+ xmlns="http://www.w3.org/2000/svg"
847
+ viewBox="0 0 24 24"
848
+ fill="none"
849
+ stroke="currentColor"
850
+ stroke-width="2"
851
+ stroke-linecap="round"
852
+ stroke-linejoin="round"
853
+ >
854
+ <circle cx="12" cy="12" r="10" />
855
+ <line x1="9" y1="9" x2="15" y2="15" />
856
+ <line x1="15" y1="9" x2="9" y2="15" />
857
+ </svg>
858
+ }
859
+ @case ('info') {
860
+ <svg
861
+ aria-hidden="true"
862
+ xmlns="http://www.w3.org/2000/svg"
863
+ viewBox="0 0 24 24"
864
+ fill="none"
865
+ stroke="currentColor"
866
+ stroke-width="1.75"
867
+ stroke-linecap="round"
868
+ stroke-linejoin="round"
869
+ >
870
+ <circle cx="12" cy="12" r="10" />
871
+ <line x1="12" y1="16" x2="12" y2="12" />
872
+ <line x1="12" y1="8" x2="12.01" y2="8" />
873
+ </svg>
874
+ }
875
+ @case ('warning') {
876
+ <svg
877
+ aria-hidden="true"
878
+ xmlns="http://www.w3.org/2000/svg"
879
+ fill="none"
880
+ viewBox="0 0 24 24"
881
+ >
882
+ <path
883
+ stroke="currentColor"
884
+ stroke-linecap="round"
885
+ stroke-linejoin="round"
886
+ stroke-width="1.75"
887
+ d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"
888
+ />
889
+ </svg>
890
+ }
891
+ @case ('loading') {
892
+ <div class="toast-icon-loading" aria-hidden="true"></div>
893
+ }
894
+ @case ('description') {}
895
+ @case ('default') {}
896
+ }
897
+ }
898
+ </span>
899
+ }
900
+
901
+ @if (hasDescription()) {
902
+ <div class="stack">
903
+ @if (toast()?.contentComponent) {
904
+ <div class="msg" [class]="resolvedClassNames()?.message">
905
+ <ng-container
906
+ *ngComponentOutlet="
907
+ toast()!.contentComponent!;
908
+ inputs: contentComponentOutletInputs()
909
+ "
910
+ />
911
+ </div>
912
+ } @else {
913
+ <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
914
+ }
915
+ @if (toast()?.description) {
916
+ <p class="description" [class]="resolvedClassNames()?.description">
917
+ {{ toast()!.description }}
918
+ </p>
919
+ }
920
+ </div>
921
+ } @else {
922
+ @if (toast()?.contentComponent) {
923
+ <div class="msg" [class]="resolvedClassNames()?.message">
924
+ <ng-container
925
+ *ngComponentOutlet="
926
+ toast()!.contentComponent!;
927
+ inputs: contentComponentOutletInputs()
928
+ "
929
+ />
930
+ </div>
931
+ } @else {
932
+ <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
933
+ }
934
+ }
935
+
936
+ @if (toast()?.toastAction; as rowAction) {
937
+ @switch (rowAction.role) {
938
+ @case ('action') {
939
+ <button
940
+ type="button"
941
+ class="toast-row-btn action-btn"
942
+ [class]="resolvedClassNames()?.actionButton"
943
+ [attr.data-row-btn]="rowAction.role"
944
+ (pointerdown)="onRowButtonPointerDown($event)"
945
+ (click)="onToastRowClick($event)"
946
+ >
947
+ {{ rowAction.label }}
948
+ </button>
949
+ }
950
+ @case ('cancel') {
951
+ <button
952
+ type="button"
953
+ class="toast-row-btn cancel-btn"
954
+ [class]="resolvedClassNames()?.cancelButton"
955
+ [attr.data-row-btn]="rowAction.role"
956
+ (pointerdown)="onRowButtonPointerDown($event)"
957
+ (click)="onToastRowClick($event)"
958
+ >
959
+ {{ rowAction.label }}
960
+ </button>
961
+ }
962
+ }
963
+ }
964
+ }
965
+
966
+ @if (showCloseButton()) {
967
+ <button
968
+ type="button"
969
+ class="close-btn"
970
+ [class]="resolvedClassNames()?.closeButton"
971
+ [animate.enter]="closeButtonEnterClass()"
972
+ [animate.leave]="closeButtonLeaveClass()"
973
+ (click)="toaster.dismiss(toast()?.id ?? '')"
974
+ [attr.aria-label]="dismissButtonAriaLabel()"
975
+ >
976
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
977
+ <path
978
+ stroke="currentColor"
979
+ stroke-linecap="round"
980
+ stroke-linejoin="round"
981
+ stroke-width="1.75"
982
+ d="M6 18 18 6M6 6l12 12"
983
+ />
984
+ </svg>
985
+ </button>
986
+ }
987
+ `, isInline: true, styles: [":host{--_chrome-bg: var(--toast-bg);--_chrome-fg: var(--toast-color);--_chrome-border: var(--toast-border-color);--_icon-fill: light-dark(var(--toast-color), var(--toast-bg));--_icon-stroke: light-dark(var(--toast-bg), var(--toast-color));--_icon-color: var(--_icon-stroke);--_toast-x: 0%;--_toast-y: 0px;--_toast-enter-y: 0px;--_toast-leave-y: 0px;--toast-line-height: 1.35;--index: 0;--collapsed-peek: 14px;--offset: calc(var(--index, 0) * var(--collapsed-peek));display:flex;align-items:center;gap:.375rem;flex:1;min-width:0;width:100%;padding-inline:.75rem;padding-block:1rem;box-sizing:border-box;border:1px solid var(--_chrome-border);border-radius:.5rem;box-shadow:var(--toast-shadow);background:var(--_chrome-bg);color:var(--_chrome-fg);font:500 .875rem/var(--toast-line-height) system-ui,sans-serif;pointer-events:auto;touch-action:none;-webkit-user-select:none;user-select:none;position:absolute;opacity:1;height:var(--initial-height, auto);scale:1;z-index:calc(1000 - var(--index, 0));transform:translate(var(--_toast-x)) translateY(var(--_toast-y));transition:opacity .4s ease,transform .4s ease,scale .4s ease,height .4s ease,box-shadow .2s ease}@starting-style{:host{opacity:0;transform:translate(var(--_toast-x)) translateY(var(--_toast-enter-y))}}:host>*:not(.close-btn){transition:opacity .4s ease}:host([data-expanded=\"true\"]):after{content:\"\";position:absolute;left:0;width:100%;height:calc(var(--toast-gap, 16px) + 1px);bottom:100%;pointer-events:auto}:host([data-variant=\"loading\"]){touch-action:auto}:host([data-position^=\"bottom\"]){bottom:0;transform-origin:50% 100%;--_toast-y: calc(-1 * var(--offset, 0px));--_toast-enter-y: 100%}:host([data-position^=\"top\"]){top:0;transform-origin:50% 0;--_toast-y: calc(1 * var(--offset, 0px));--_toast-enter-y: -100%}:host([data-swipe-direction=\"down\"]){--_toast-leave-y: 100%}:host([data-swipe-direction=\"up\"]){--_toast-leave-y: -100%}:host([data-expanded=\"false\"]){scale:calc(1 - var(--index, 0) * .05)}:host([data-expanded=\"false\"]:not(:last-child)){height:var(--front-toast-height);overflow:hidden}:host([data-expanded=\"false\"]:not(:last-child):not([data-headless=\"true\"]))>*:not(.close-btn){opacity:0;pointer-events:none}:host([data-expanded=\"false\"]:nth-last-child(n + 4)){opacity:0;pointer-events:none}:host([data-rich-colors=\"true\"][data-variant=\"success\"]){--_chrome-bg: var(--toast-success-bg);--_chrome-fg: var(--toast-success-text);--_chrome-border: var(--toast-success-border)}:host([data-rich-colors=\"true\"][data-variant=\"error\"]){--_chrome-bg: var(--toast-error-bg);--_chrome-fg: var(--toast-error-text);--_chrome-border: var(--toast-error-border)}:host([data-rich-colors=\"true\"][data-variant=\"info\"]){--_chrome-bg: var(--toast-info-bg);--_chrome-fg: var(--toast-info-text);--_chrome-border: var(--toast-info-border)}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]){--_chrome-bg: var(--toast-warning-bg);--_chrome-fg: var(--toast-warning-text);--_chrome-border: var(--toast-warning-border)}:host([data-rich-colors=\"true\"]:is([data-variant=\"success\"],[data-variant=\"error\"],[data-variant=\"info\"],[data-variant=\"warning\"])){--_icon-fill: light-dark(var(--_chrome-fg), var(--_chrome-bg));--_icon-stroke: light-dark(var(--_chrome-bg), var(--_chrome-fg));--_icon-color: var(--_icon-stroke)}:host([data-headless=\"true\"]){width:max-content;max-width:calc(100dvw - var(--toast-offset-mobile-left, 16px) - var(--toast-offset-mobile-right, 16px));padding:0;gap:0;border:none;border-radius:0;box-shadow:none;background:transparent;color:inherit;font:inherit;line-height:normal;--toast-line-height: inherit}@starting-style{:host([data-headless=\"true\"]){opacity:1}}:host([data-headless=\"true\"][data-position=\"bottom-center\"]),:host([data-headless=\"true\"][data-position=\"top-center\"]){left:50%;right:auto;--_toast-x: -50%}:host([data-headless=\"true\"][data-icon=\"false\"]){padding-left:0}:host([data-icon=\"false\"]){padding-left:.925rem}@media(width>=40rem){:host{width:var(--toast-width)}:host([data-headless=\"true\"]){max-width:calc(100dvw - var(--toast-offset-left, 24px) - var(--toast-offset-right, 24px))}:host([data-headless=\"true\"][data-position$=\"-right\"]){left:auto;right:0}:host([data-headless=\"true\"][data-position$=\"-left\"]){left:0;right:auto}}@media(width<40rem){:host([data-headless=\"true\"][data-position^=\"bottom\"]),:host([data-headless=\"true\"][data-position^=\"top\"]){left:50%;right:auto;--_toast-x: -50%}}.toast-icon,.toast-icon ::ng-deep{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.425rem;height:1.425rem}.toast-icon svg,.toast-icon ::ng-deep svg{display:block;margin-inline:auto;fill:var(--_icon-fill);stroke:var(--_icon-stroke);color:var(--_icon-color);width:95%;height:95%}:host([data-theme=\"dark\"]) .toast-icon svg,:host([data-theme=\"dark\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}@media(prefers-color-scheme:dark){:host([data-theme=\"system\"]) .toast-icon svg,:host([data-theme=\"system\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}}.toast-icon-loading{display:block;width:.9rem;height:.9rem;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;border-right-color:transparent;animation:spin .45s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.msg{flex:1;min-width:0;max-width:95%;margin:0;font-size:.825rem;font-weight:500;line-height:calc(1.25 / .875);letter-spacing:.01em}@media(width<40rem){.msg{max-width:90%;font-size:.8rem}}.stack{display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;flex:1;min-width:0}.stack .msg{flex:0 1 auto;max-width:100%}:host([data-icon=\"false\"]) .stack .msg{max-width:90%}.description{margin:0;font-size:.825rem;font-weight:400;line-height:1.35;letter-spacing:.01em;opacity:.9;max-width:100%}@media(width<40rem){.description{font-size:.8rem}}.toast-row-btn{flex-shrink:0;margin:0;margin-inline-start:auto;padding:.35rem .65rem;border-radius:.375rem;border:1px solid transparent;font:inherit;font-size:.8rem;font-weight:600;letter-spacing:.01em;line-height:1.2;cursor:pointer;white-space:nowrap;transition:transform .2s ease}.toast-row-btn:focus-visible{outline:2px solid var(--toast-color);outline-offset:2px}.toast-row-btn:active{transform:scale(.95)}.action-btn{background:var(--toast-action-bg);color:var(--toast-action-text);border-color:var(--toast-action-border)}.cancel-btn{background:var(--toast-cancel-bg);color:var(--toast-color);border-color:var(--toast-cancel-border)}.toast-custom{flex:1;min-width:0;width:100%;font-size:.825rem;font-weight:400;line-height:calc(1.25 / .875)}.toast-custom :first-child{margin-top:0}.toast-custom :last-child{margin-bottom:0}.close-btn{position:absolute;top:-.3875rem;right:-.3875rem;flex-shrink:0;margin:-.15rem -.25rem -.15rem 0;border:1px solid var(--_chrome-border);box-shadow:var(--toast-shadow);background:var(--_chrome-bg);color:var(--_chrome-fg);cursor:pointer;line-height:1;padding:.25rem;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;opacity:1;scale:1;filter:blur(0)}.close-btn.close-enter{opacity:1;scale:1;filter:blur(0);transition:opacity .18s cubic-bezier(.19,1,.22,1),scale .18s cubic-bezier(.19,1,.22,1),filter .18s cubic-bezier(.19,1,.22,1)}@starting-style{.close-btn.close-enter{opacity:0;scale:.92;filter:blur(4px)}}.close-btn.close-leave{opacity:0;scale:.92;filter:blur(4px);pointer-events:none;transition:opacity .15s cubic-bezier(.19,1,.22,1),scale .15s cubic-bezier(.19,1,.22,1),filter .15s cubic-bezier(.19,1,.22,1)}.close-btn:focus-visible{outline:2px solid currentColor}.close-btn svg{display:block;width:.825rem;height:.825rem}:host(.leave){opacity:0;scale:.95;transform:translate(var(--_toast-x)) translateY(var(--_toast-leave-y))}@media(prefers-reduced-motion:reduce){:host{transition:none}:host([data-position]){--_toast-enter-y: var(--_toast-y);--_toast-leave-y: var(--_toast-y)}:host>*{transition:none}:host(.leave){scale:1}.toast-row-btn:active{transform:none}.close-btn.close-enter{scale:1;filter:none;transition:opacity .15s ease}@starting-style{.close-btn.close-enter{opacity:0;scale:1;filter:none}}.close-btn.close-leave{scale:1;filter:none;transition:opacity .15s ease}.toast-icon-loading{animation:none}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
894
988
  }
895
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BetterToastItem, decorators: [{
989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: BetterToastItem, decorators: [{
896
990
  type: Component,
897
991
  args: [{ selector: 'li[betterToastItem]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgComponentOutlet], host: {
898
992
  role: 'listitem',
@@ -904,7 +998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
904
998
  '[attr.data-headless]': 'isHeadless() ? "true" : null',
905
999
  '[attr.data-swipe-direction]': 'swipeDirection()',
906
1000
  '[attr.data-theme]': 'theme()',
907
- '[style.--offset]': 'offset() + "px"',
1001
+ '[style.--initial-height]': 'initialHeightCss()',
908
1002
  '[style]': 'isHeadless() ? undefined : hostStyle()',
909
1003
  '[animate.leave]': '"leave"',
910
1004
  '(pointerdown)': 'onPointerDown($event)',
@@ -912,190 +1006,194 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
912
1006
  '(pointerup)': 'onPointerUp()',
913
1007
  '(pointercancel)': 'onPointerCancel()',
914
1008
  '(pointerenter)': 'onPointerEnter()',
915
- '(pointerleave)': 'onPointerLeave()',
916
- }, template: `
917
- @if (toast()?.component) {
918
- <ng-container *ngComponentOutlet="toast()!.component!; inputs: componentOutletInputs()" />
919
- } @else {
920
- @if (shouldShowIconColumn()) {
921
- <span class="toast-icon" aria-hidden="true">
922
- @if (toast()?.icon) {
923
- <ng-container *ngComponentOutlet="toast()!.icon!" />
924
- } @else if (iconComponent(); as IconCmp) {
925
- <ng-container *ngComponentOutlet="IconCmp" />
926
- } @else {
927
- @switch (variant()) {
928
- @case ('success') {
929
- <svg
930
- xmlns="http://www.w3.org/2000/svg"
931
- fill="none"
932
- viewBox="0 0 24 24"
933
- aria-hidden="true"
934
- >
935
- <circle
936
- cx="12"
937
- cy="12"
938
- r="9"
939
- stroke="currentColor"
940
- stroke-linecap="round"
941
- stroke-linejoin="round"
942
- stroke-width="1.75"
943
- />
944
- <path
945
- stroke="currentColor"
946
- stroke-linecap="round"
947
- stroke-linejoin="round"
948
- stroke-width="1.75"
949
- d="M8.48 12.22 10.9 14.64 15.74 9.14"
950
- />
951
- </svg>
952
- }
953
- @case ('error') {
954
- <svg
955
- aria-hidden="true"
956
- xmlns="http://www.w3.org/2000/svg"
957
- viewBox="0 0 24 24"
958
- fill="none"
959
- stroke="currentColor"
960
- stroke-width="2"
961
- stroke-linecap="round"
962
- stroke-linejoin="round"
963
- >
964
- <circle cx="12" cy="12" r="10" />
965
- <line x1="9" y1="9" x2="15" y2="15" />
966
- <line x1="15" y1="9" x2="9" y2="15" />
967
- </svg>
968
- }
969
- @case ('info') {
970
- <svg
971
- aria-hidden="true"
972
- xmlns="http://www.w3.org/2000/svg"
973
- viewBox="0 0 24 24"
974
- fill="none"
975
- stroke="currentColor"
976
- stroke-width="1.75"
977
- stroke-linecap="round"
978
- stroke-linejoin="round"
979
- >
980
- <circle cx="12" cy="12" r="10" />
981
- <line x1="12" y1="16" x2="12" y2="12" />
982
- <line x1="12" y1="8" x2="12.01" y2="8" />
983
- </svg>
984
- }
985
- @case ('warning') {
986
- <svg
987
- aria-hidden="true"
988
- xmlns="http://www.w3.org/2000/svg"
989
- fill="none"
990
- viewBox="0 0 24 24"
991
- >
992
- <path
993
- stroke="currentColor"
994
- stroke-linecap="round"
995
- stroke-linejoin="round"
996
- stroke-width="1.75"
997
- d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"
998
- />
999
- </svg>
1000
- }
1001
- @case ('loading') {
1002
- <div class="toast-icon-loading" aria-hidden="true"></div>
1003
- }
1004
- @case ('description') {}
1005
- @case ('default') {}
1006
- }
1007
- }
1008
- </span>
1009
- }
1010
-
1011
- @if (hasDescription()) {
1012
- <div class="stack">
1013
- @if (toast()?.contentComponent) {
1014
- <div class="msg" [class]="resolvedClassNames()?.message">
1015
- <ng-container
1016
- *ngComponentOutlet="
1017
- toast()!.contentComponent!;
1018
- inputs: contentComponentOutletInputs()
1019
- "
1020
- />
1021
- </div>
1022
- } @else {
1023
- <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
1024
- }
1025
- @if (toast()?.description) {
1026
- <p class="description" [class]="resolvedClassNames()?.description">
1027
- {{ toast()!.description }}
1028
- </p>
1029
- }
1030
- </div>
1031
- } @else {
1032
- @if (toast()?.contentComponent) {
1033
- <div class="msg" [class]="resolvedClassNames()?.message">
1034
- <ng-container
1035
- *ngComponentOutlet="
1036
- toast()!.contentComponent!;
1037
- inputs: contentComponentOutletInputs()
1038
- "
1039
- />
1040
- </div>
1041
- } @else {
1042
- <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
1043
- }
1044
- }
1045
-
1046
- @if (toast()?.toastAction; as rowAction) {
1047
- @switch (rowAction.role) {
1048
- @case ('action') {
1049
- <button
1050
- type="button"
1051
- class="toast-row-btn action-btn"
1052
- [class]="resolvedClassNames()?.actionButton"
1053
- [attr.data-row-btn]="rowAction.role"
1054
- (pointerdown)="onRowButtonPointerDown($event)"
1055
- (click)="onToastRowClick($event)"
1056
- >
1057
- {{ rowAction.label }}
1058
- </button>
1059
- }
1060
- @case ('cancel') {
1061
- <button
1062
- type="button"
1063
- class="toast-row-btn cancel-btn"
1064
- [class]="resolvedClassNames()?.cancelButton"
1065
- [attr.data-row-btn]="rowAction.role"
1066
- (pointerdown)="onRowButtonPointerDown($event)"
1067
- (click)="onToastRowClick($event)"
1068
- >
1069
- {{ rowAction.label }}
1070
- </button>
1071
- }
1072
- }
1073
- }
1074
- }
1075
-
1076
- @if (closeButton() && !isHeadless()) {
1077
- <button
1078
- type="button"
1079
- class="close-btn"
1080
- [class]="resolvedClassNames()?.closeButton"
1081
- (click)="toaster.dismiss(toast()?.id ?? '')"
1082
- [attr.aria-label]="dismissButtonAriaLabel()"
1083
- >
1084
- <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
1085
- <path
1086
- stroke="currentColor"
1087
- stroke-linecap="round"
1088
- stroke-linejoin="round"
1089
- stroke-width="1.75"
1090
- d="M6 18 18 6M6 6l12 12"
1091
- />
1092
- </svg>
1093
- </button>
1094
- }
1095
- `, styles: [":host{display:flex;align-items:center;gap:.375rem;flex:1;min-width:0;width:100%;padding-inline:.75rem;padding-block:1rem;box-sizing:border-box;border:1px solid var(--toast-border-color);border-radius:.5rem;box-shadow:var(--toast-shadow);background:var(--toast-bg);color:var(--toast-color);--toast-line-height: 1.35;font:500 .875rem/var(--toast-line-height) system-ui,sans-serif;pointer-events:auto;touch-action:none;-webkit-user-select:none;user-select:none;position:absolute;opacity:1;scale:1;transition:opacity .4s ease,transform .4s ease,scale .4s ease,box-shadow .2s ease}:host([data-variant=\"loading\"]){touch-action:auto}@media(width>=40rem){:host{width:var(--toast-width)}}:host([data-position^=\"bottom\"]){bottom:0;transform:translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-position^=\"bottom\"]){opacity:0;transform:translateY(100%)}}:host([data-position^=\"top\"]){top:0;transform:translateY(calc(1 * var(--offset, 0px)))}@starting-style{:host([data-position^=\"top\"]){opacity:0;transform:translateY(-100%)}}@starting-style{:host([data-headless=\"true\"][data-position^=\"bottom\"]){opacity:1}}@starting-style{:host([data-headless=\"true\"][data-position^=\"top\"]){opacity:1}}:host([data-variant=\"default\"]) .toast-icon svg,:host([data-variant=\"default\"]) .toast-icon ::ng-deep svg,:host([data-variant=\"description\"]) .toast-icon svg,:host([data-variant=\"description\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"success\"]){background:var(--toast-success-bg);color:var(--toast-success-text);border-color:var(--toast-success-border)}:host([data-rich-colors=\"false\"][data-variant=\"success\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"success\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"success\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"success\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-success-text),var(--toast-success-bg));stroke:light-dark(var(--toast-success-bg),var(--toast-success-text));color:light-dark(var(--toast-success-bg),var(--toast-success-text))}:host([data-rich-colors=\"true\"][data-variant=\"error\"]){background:var(--toast-error-bg);color:var(--toast-error-text);border-color:var(--toast-error-border)}:host([data-rich-colors=\"false\"][data-variant=\"error\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"error\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"error\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"error\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-error-text),var(--toast-error-bg));stroke:light-dark(var(--toast-error-bg),var(--toast-error-text));color:light-dark(var(--toast-error-bg),var(--toast-error-text))}:host([data-rich-colors=\"true\"][data-variant=\"info\"]){background:var(--toast-info-bg);color:var(--toast-info-text);border-color:var(--toast-info-border)}:host([data-rich-colors=\"false\"][data-variant=\"info\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"info\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"info\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"info\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-info-text),var(--toast-info-bg));stroke:light-dark(var(--toast-info-bg),var(--toast-info-text));color:light-dark(var(--toast-info-bg),var(--toast-info-text))}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]){background:var(--toast-warning-bg);color:var(--toast-warning-text);border-color:var(--toast-warning-border)}:host([data-rich-colors=\"false\"][data-variant=\"warning\"]) .toast-icon svg,:host([data-rich-colors=\"false\"][data-variant=\"warning\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-color),var(--toast-bg));color:light-dark(var(--toast-bg),var(--toast-color))}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]) .toast-icon svg,:host([data-rich-colors=\"true\"][data-variant=\"warning\"]) .toast-icon ::ng-deep svg{fill:light-dark(var(--toast-warning-text),var(--toast-warning-bg));stroke:light-dark(var(--toast-warning-bg),var(--toast-warning-text));color:light-dark(var(--toast-warning-bg),var(--toast-warning-text))}:host([data-headless=\"true\"]){width:max-content;max-width:calc(100dvw - var(--toast-offset-mobile-left, 16px) - var(--toast-offset-mobile-right, 16px));padding:0;gap:0;border:none;border-radius:0;box-shadow:none;background:transparent;color:inherit;font:inherit;line-height:normal;--toast-line-height: inherit}@media(width>=40rem){:host([data-headless=\"true\"]){max-width:calc(100dvw - var(--toast-offset-left, 24px) - var(--toast-offset-right, 24px))}}@media(width>=40rem){:host([data-headless=\"true\"][data-position$=\"-right\"]){left:auto;right:0}:host([data-headless=\"true\"][data-position$=\"-left\"]){left:0;right:auto}}:host([data-headless=\"true\"][data-position=\"bottom-center\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position=\"bottom-center\"]){opacity:1;transform:translate(-50%) translateY(100%)}}:host([data-headless=\"true\"][data-position=\"top-center\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position=\"top-center\"]){opacity:1;transform:translate(-50%) translateY(-100%)}}@media(width<40rem){:host([data-headless=\"true\"][data-position^=\"bottom\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position^=\"bottom\"]){opacity:1;transform:translate(-50%) translateY(100%)}}:host([data-headless=\"true\"][data-position^=\"top\"]){left:50%;right:auto;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position^=\"top\"]){opacity:1;transform:translate(-50%) translateY(-100%)}}:host([data-headless=\"true\"][data-swipe-direction=\"down\"].leave){transform:translate(-50%) translateY(100%)}:host([data-headless=\"true\"][data-swipe-direction=\"up\"].leave){transform:translate(-50%) translateY(-100%)}}:host([data-headless=\"true\"][data-rich-colors=\"true\"]){background:transparent;color:inherit;border-color:transparent}:host([data-headless=\"true\"][data-icon=\"false\"]){padding-left:0}:host([data-icon=\"false\"]){padding-left:.925rem}.toast-icon,.toast-icon ::ng-deep{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.425rem;height:1.425rem}.toast-icon svg,.toast-icon ::ng-deep svg{display:block;margin-inline:auto;fill:light-dark(var(--toast-color),var(--toast-bg));stroke:light-dark(var(--toast-bg),var(--toast-color));width:95%;height:95%}:host([data-theme=\"dark\"]) .toast-icon svg,:host([data-theme=\"dark\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}@media(prefers-color-scheme:dark){:host([data-theme=\"system\"]) .toast-icon svg,:host([data-theme=\"system\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}}.toast-icon-loading{display:block;width:.9rem;height:.9rem;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;border-right-color:transparent;animation:spin .45s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.msg{flex:1;min-width:0;max-width:95%;margin:0;font-size:.825rem;font-weight:500;line-height:calc(1.25 / .875);letter-spacing:.01em}@media(width<40rem){.msg{max-width:90%;font-size:.8rem}}.stack{display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;flex:1;min-width:0}.stack .msg{flex:0 1 auto;max-width:100%}:host([data-icon=\"false\"]) .stack .msg{max-width:90%}.description{margin:0;font-size:.825rem;font-weight:400;line-height:1.35;letter-spacing:.01em;opacity:.9;max-width:100%}@media(width<40rem){.description{font-size:.8rem}}.toast-row-btn{flex-shrink:0;margin:0;margin-inline-start:auto;padding:.35rem .65rem;border-radius:.375rem;border:1px solid transparent;font:inherit;font-size:.8rem;font-weight:600;letter-spacing:.01em;line-height:1.2;cursor:pointer;white-space:nowrap;transition:transform .2s ease}.toast-row-btn:focus-visible{outline:2px solid var(--toast-color);outline-offset:2px}.toast-row-btn:active{transform:scale(.95)}@media(prefers-reduced-motion:reduce){.toast-row-btn:active{transform:none}}.action-btn{background:var(--toast-action-bg);color:var(--toast-action-text);border-color:var(--toast-action-border)}.cancel-btn{background:var(--toast-cancel-bg);color:var(--toast-color);border-color:var(--toast-cancel-border)}.toast-custom{flex:1;min-width:0;width:100%;font-size:.825rem;font-weight:400;line-height:calc(1.25 / .875)}.toast-custom :first-child{margin-top:0}.toast-custom :last-child{margin-bottom:0}.close-btn{position:absolute;top:-.3875rem;right:-.3875rem;flex-shrink:0;margin:-.15rem -.25rem -.15rem 0;border:1px solid var(--toast-border-color);box-shadow:var(--toast-shadow);background:var(--toast-bg);color:var(--toast-color);cursor:pointer;line-height:1;padding:.25rem;border-radius:50%;display:inline-flex;align-items:center;justify-content:center}:host([data-rich-colors=\"true\"][data-variant=\"success\"]) .close-btn{border-color:var(--toast-success-border);background:var(--toast-success-bg);color:var(--toast-success-text)}:host([data-rich-colors=\"true\"][data-variant=\"error\"]) .close-btn{border-color:var(--toast-error-border);background:var(--toast-error-bg);color:var(--toast-error-text)}:host([data-rich-colors=\"true\"][data-variant=\"info\"]) .close-btn{border-color:var(--toast-info-border);background:var(--toast-info-bg);color:var(--toast-info-text)}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]) .close-btn{border-color:var(--toast-warning-border);background:var(--toast-warning-bg);color:var(--toast-warning-text)}.close-btn:focus-visible{outline:2px solid currentColor}.close-btn svg{display:block;width:.825rem;height:.825rem}:host(.leave){opacity:0;scale:.95}:host([data-swipe-direction=\"down\"].leave){transform:translateY(100%)}:host([data-headless=\"true\"][data-position=\"bottom-center\"].leave){transform:translate(-50%) translateY(100%)}:host([data-swipe-direction=\"up\"].leave){transform:translateY(-100%)}:host([data-headless=\"true\"][data-position=\"top-center\"].leave){transform:translate(-50%) translateY(-100%)}@media(prefers-reduced-motion:reduce){:host{transition:none}:host(.leave){scale:1}@starting-style{:host([data-position^=\"bottom\"]){opacity:0;transform:translateY(calc(-1 * var(--offset, 0px)))}}@starting-style{:host([data-position^=\"top\"]){opacity:0;transform:translateY(calc(1 * var(--offset, 0px)))}}@starting-style{:host([data-headless=\"true\"][data-position=\"bottom-center\"]){opacity:1;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}}@starting-style{:host([data-headless=\"true\"][data-position=\"top-center\"]){opacity:1;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}}:host([data-swipe-direction=\"down\"].leave){transform:translateY(calc(-1 * var(--offset, 0px)))}:host([data-swipe-direction=\"up\"].leave){transform:translateY(calc(1 * var(--offset, 0px)))}:host([data-headless=\"true\"][data-position=\"bottom-center\"].leave){transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}:host([data-headless=\"true\"][data-position=\"top-center\"].leave){transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}@media(width<40rem){@starting-style{:host([data-headless=\"true\"][data-position^=\"bottom\"]){opacity:1;transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}}:host([data-headless=\"true\"][data-swipe-direction=\"down\"].leave){transform:translate(-50%) translateY(calc(-1 * var(--offset, 0px)))}@starting-style{:host([data-headless=\"true\"][data-position^=\"top\"]){opacity:1;transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}}:host([data-headless=\"true\"][data-swipe-direction=\"up\"].leave){transform:translate(-50%) translateY(calc(1 * var(--offset, 0px)))}}.toast-icon-loading{animation:none}}\n"] }]
1096
- }], ctorParameters: () => [], propDecorators: { toast: [{ type: i0.Input, args: [{ isSignal: true, alias: "toast", required: false }] }], toasterStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "toasterStyle", required: false }] }], toasterClassNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "toasterClassNames", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: true }] }], closeButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButton", required: false }] }], customIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "customIcons", required: false }] }], dismissButtonAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissButtonAriaLabel", required: false }] }], stackPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "stackPosition", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], heightChange: [{ type: i0.Output, args: ["heightChange"] }] } });
1009
+ '(pointerleave)': 'onPointerLeave($event)',
1010
+ }, template: `
1011
+ @if (toast()?.component) {
1012
+ <ng-container *ngComponentOutlet="toast()!.component!; inputs: componentOutletInputs()" />
1013
+ } @else {
1014
+ @if (shouldShowIconColumn()) {
1015
+ <span class="toast-icon" aria-hidden="true">
1016
+ @if (toast()?.icon) {
1017
+ <ng-container *ngComponentOutlet="toast()!.icon!" />
1018
+ } @else if (iconComponent(); as IconCmp) {
1019
+ <ng-container *ngComponentOutlet="IconCmp" />
1020
+ } @else {
1021
+ @switch (variant()) {
1022
+ @case ('success') {
1023
+ <svg
1024
+ xmlns="http://www.w3.org/2000/svg"
1025
+ fill="none"
1026
+ viewBox="0 0 24 24"
1027
+ aria-hidden="true"
1028
+ >
1029
+ <circle
1030
+ cx="12"
1031
+ cy="12"
1032
+ r="9"
1033
+ stroke="currentColor"
1034
+ stroke-linecap="round"
1035
+ stroke-linejoin="round"
1036
+ stroke-width="1.75"
1037
+ />
1038
+ <path
1039
+ stroke="currentColor"
1040
+ stroke-linecap="round"
1041
+ stroke-linejoin="round"
1042
+ stroke-width="1.75"
1043
+ d="M8.48 12.22 10.9 14.64 15.74 9.14"
1044
+ />
1045
+ </svg>
1046
+ }
1047
+ @case ('error') {
1048
+ <svg
1049
+ aria-hidden="true"
1050
+ xmlns="http://www.w3.org/2000/svg"
1051
+ viewBox="0 0 24 24"
1052
+ fill="none"
1053
+ stroke="currentColor"
1054
+ stroke-width="2"
1055
+ stroke-linecap="round"
1056
+ stroke-linejoin="round"
1057
+ >
1058
+ <circle cx="12" cy="12" r="10" />
1059
+ <line x1="9" y1="9" x2="15" y2="15" />
1060
+ <line x1="15" y1="9" x2="9" y2="15" />
1061
+ </svg>
1062
+ }
1063
+ @case ('info') {
1064
+ <svg
1065
+ aria-hidden="true"
1066
+ xmlns="http://www.w3.org/2000/svg"
1067
+ viewBox="0 0 24 24"
1068
+ fill="none"
1069
+ stroke="currentColor"
1070
+ stroke-width="1.75"
1071
+ stroke-linecap="round"
1072
+ stroke-linejoin="round"
1073
+ >
1074
+ <circle cx="12" cy="12" r="10" />
1075
+ <line x1="12" y1="16" x2="12" y2="12" />
1076
+ <line x1="12" y1="8" x2="12.01" y2="8" />
1077
+ </svg>
1078
+ }
1079
+ @case ('warning') {
1080
+ <svg
1081
+ aria-hidden="true"
1082
+ xmlns="http://www.w3.org/2000/svg"
1083
+ fill="none"
1084
+ viewBox="0 0 24 24"
1085
+ >
1086
+ <path
1087
+ stroke="currentColor"
1088
+ stroke-linecap="round"
1089
+ stroke-linejoin="round"
1090
+ stroke-width="1.75"
1091
+ d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"
1092
+ />
1093
+ </svg>
1094
+ }
1095
+ @case ('loading') {
1096
+ <div class="toast-icon-loading" aria-hidden="true"></div>
1097
+ }
1098
+ @case ('description') {}
1099
+ @case ('default') {}
1100
+ }
1101
+ }
1102
+ </span>
1103
+ }
1104
+
1105
+ @if (hasDescription()) {
1106
+ <div class="stack">
1107
+ @if (toast()?.contentComponent) {
1108
+ <div class="msg" [class]="resolvedClassNames()?.message">
1109
+ <ng-container
1110
+ *ngComponentOutlet="
1111
+ toast()!.contentComponent!;
1112
+ inputs: contentComponentOutletInputs()
1113
+ "
1114
+ />
1115
+ </div>
1116
+ } @else {
1117
+ <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
1118
+ }
1119
+ @if (toast()?.description) {
1120
+ <p class="description" [class]="resolvedClassNames()?.description">
1121
+ {{ toast()!.description }}
1122
+ </p>
1123
+ }
1124
+ </div>
1125
+ } @else {
1126
+ @if (toast()?.contentComponent) {
1127
+ <div class="msg" [class]="resolvedClassNames()?.message">
1128
+ <ng-container
1129
+ *ngComponentOutlet="
1130
+ toast()!.contentComponent!;
1131
+ inputs: contentComponentOutletInputs()
1132
+ "
1133
+ />
1134
+ </div>
1135
+ } @else {
1136
+ <p class="msg" [class]="resolvedClassNames()?.message">{{ toast()?.message }}</p>
1137
+ }
1138
+ }
1139
+
1140
+ @if (toast()?.toastAction; as rowAction) {
1141
+ @switch (rowAction.role) {
1142
+ @case ('action') {
1143
+ <button
1144
+ type="button"
1145
+ class="toast-row-btn action-btn"
1146
+ [class]="resolvedClassNames()?.actionButton"
1147
+ [attr.data-row-btn]="rowAction.role"
1148
+ (pointerdown)="onRowButtonPointerDown($event)"
1149
+ (click)="onToastRowClick($event)"
1150
+ >
1151
+ {{ rowAction.label }}
1152
+ </button>
1153
+ }
1154
+ @case ('cancel') {
1155
+ <button
1156
+ type="button"
1157
+ class="toast-row-btn cancel-btn"
1158
+ [class]="resolvedClassNames()?.cancelButton"
1159
+ [attr.data-row-btn]="rowAction.role"
1160
+ (pointerdown)="onRowButtonPointerDown($event)"
1161
+ (click)="onToastRowClick($event)"
1162
+ >
1163
+ {{ rowAction.label }}
1164
+ </button>
1165
+ }
1166
+ }
1167
+ }
1168
+ }
1169
+
1170
+ @if (showCloseButton()) {
1171
+ <button
1172
+ type="button"
1173
+ class="close-btn"
1174
+ [class]="resolvedClassNames()?.closeButton"
1175
+ [animate.enter]="closeButtonEnterClass()"
1176
+ [animate.leave]="closeButtonLeaveClass()"
1177
+ (click)="toaster.dismiss(toast()?.id ?? '')"
1178
+ [attr.aria-label]="dismissButtonAriaLabel()"
1179
+ >
1180
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
1181
+ <path
1182
+ stroke="currentColor"
1183
+ stroke-linecap="round"
1184
+ stroke-linejoin="round"
1185
+ stroke-width="1.75"
1186
+ d="M6 18 18 6M6 6l12 12"
1187
+ />
1188
+ </svg>
1189
+ </button>
1190
+ }
1191
+ `, styles: [":host{--_chrome-bg: var(--toast-bg);--_chrome-fg: var(--toast-color);--_chrome-border: var(--toast-border-color);--_icon-fill: light-dark(var(--toast-color), var(--toast-bg));--_icon-stroke: light-dark(var(--toast-bg), var(--toast-color));--_icon-color: var(--_icon-stroke);--_toast-x: 0%;--_toast-y: 0px;--_toast-enter-y: 0px;--_toast-leave-y: 0px;--toast-line-height: 1.35;--index: 0;--collapsed-peek: 14px;--offset: calc(var(--index, 0) * var(--collapsed-peek));display:flex;align-items:center;gap:.375rem;flex:1;min-width:0;width:100%;padding-inline:.75rem;padding-block:1rem;box-sizing:border-box;border:1px solid var(--_chrome-border);border-radius:.5rem;box-shadow:var(--toast-shadow);background:var(--_chrome-bg);color:var(--_chrome-fg);font:500 .875rem/var(--toast-line-height) system-ui,sans-serif;pointer-events:auto;touch-action:none;-webkit-user-select:none;user-select:none;position:absolute;opacity:1;height:var(--initial-height, auto);scale:1;z-index:calc(1000 - var(--index, 0));transform:translate(var(--_toast-x)) translateY(var(--_toast-y));transition:opacity .4s ease,transform .4s ease,scale .4s ease,height .4s ease,box-shadow .2s ease}@starting-style{:host{opacity:0;transform:translate(var(--_toast-x)) translateY(var(--_toast-enter-y))}}:host>*:not(.close-btn){transition:opacity .4s ease}:host([data-expanded=\"true\"]):after{content:\"\";position:absolute;left:0;width:100%;height:calc(var(--toast-gap, 16px) + 1px);bottom:100%;pointer-events:auto}:host([data-variant=\"loading\"]){touch-action:auto}:host([data-position^=\"bottom\"]){bottom:0;transform-origin:50% 100%;--_toast-y: calc(-1 * var(--offset, 0px));--_toast-enter-y: 100%}:host([data-position^=\"top\"]){top:0;transform-origin:50% 0;--_toast-y: calc(1 * var(--offset, 0px));--_toast-enter-y: -100%}:host([data-swipe-direction=\"down\"]){--_toast-leave-y: 100%}:host([data-swipe-direction=\"up\"]){--_toast-leave-y: -100%}:host([data-expanded=\"false\"]){scale:calc(1 - var(--index, 0) * .05)}:host([data-expanded=\"false\"]:not(:last-child)){height:var(--front-toast-height);overflow:hidden}:host([data-expanded=\"false\"]:not(:last-child):not([data-headless=\"true\"]))>*:not(.close-btn){opacity:0;pointer-events:none}:host([data-expanded=\"false\"]:nth-last-child(n + 4)){opacity:0;pointer-events:none}:host([data-rich-colors=\"true\"][data-variant=\"success\"]){--_chrome-bg: var(--toast-success-bg);--_chrome-fg: var(--toast-success-text);--_chrome-border: var(--toast-success-border)}:host([data-rich-colors=\"true\"][data-variant=\"error\"]){--_chrome-bg: var(--toast-error-bg);--_chrome-fg: var(--toast-error-text);--_chrome-border: var(--toast-error-border)}:host([data-rich-colors=\"true\"][data-variant=\"info\"]){--_chrome-bg: var(--toast-info-bg);--_chrome-fg: var(--toast-info-text);--_chrome-border: var(--toast-info-border)}:host([data-rich-colors=\"true\"][data-variant=\"warning\"]){--_chrome-bg: var(--toast-warning-bg);--_chrome-fg: var(--toast-warning-text);--_chrome-border: var(--toast-warning-border)}:host([data-rich-colors=\"true\"]:is([data-variant=\"success\"],[data-variant=\"error\"],[data-variant=\"info\"],[data-variant=\"warning\"])){--_icon-fill: light-dark(var(--_chrome-fg), var(--_chrome-bg));--_icon-stroke: light-dark(var(--_chrome-bg), var(--_chrome-fg));--_icon-color: var(--_icon-stroke)}:host([data-headless=\"true\"]){width:max-content;max-width:calc(100dvw - var(--toast-offset-mobile-left, 16px) - var(--toast-offset-mobile-right, 16px));padding:0;gap:0;border:none;border-radius:0;box-shadow:none;background:transparent;color:inherit;font:inherit;line-height:normal;--toast-line-height: inherit}@starting-style{:host([data-headless=\"true\"]){opacity:1}}:host([data-headless=\"true\"][data-position=\"bottom-center\"]),:host([data-headless=\"true\"][data-position=\"top-center\"]){left:50%;right:auto;--_toast-x: -50%}:host([data-headless=\"true\"][data-icon=\"false\"]){padding-left:0}:host([data-icon=\"false\"]){padding-left:.925rem}@media(width>=40rem){:host{width:var(--toast-width)}:host([data-headless=\"true\"]){max-width:calc(100dvw - var(--toast-offset-left, 24px) - var(--toast-offset-right, 24px))}:host([data-headless=\"true\"][data-position$=\"-right\"]){left:auto;right:0}:host([data-headless=\"true\"][data-position$=\"-left\"]){left:0;right:auto}}@media(width<40rem){:host([data-headless=\"true\"][data-position^=\"bottom\"]),:host([data-headless=\"true\"][data-position^=\"top\"]){left:50%;right:auto;--_toast-x: -50%}}.toast-icon,.toast-icon ::ng-deep{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.425rem;height:1.425rem}.toast-icon svg,.toast-icon ::ng-deep svg{display:block;margin-inline:auto;fill:var(--_icon-fill);stroke:var(--_icon-stroke);color:var(--_icon-color);width:95%;height:95%}:host([data-theme=\"dark\"]) .toast-icon svg,:host([data-theme=\"dark\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}@media(prefers-color-scheme:dark){:host([data-theme=\"system\"]) .toast-icon svg,:host([data-theme=\"system\"]) .toast-icon ::ng-deep svg{width:87.5%;height:87.5%}}.toast-icon-loading{display:block;width:.9rem;height:.9rem;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;border-right-color:transparent;animation:spin .45s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.msg{flex:1;min-width:0;max-width:95%;margin:0;font-size:.825rem;font-weight:500;line-height:calc(1.25 / .875);letter-spacing:.01em}@media(width<40rem){.msg{max-width:90%;font-size:.8rem}}.stack{display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;flex:1;min-width:0}.stack .msg{flex:0 1 auto;max-width:100%}:host([data-icon=\"false\"]) .stack .msg{max-width:90%}.description{margin:0;font-size:.825rem;font-weight:400;line-height:1.35;letter-spacing:.01em;opacity:.9;max-width:100%}@media(width<40rem){.description{font-size:.8rem}}.toast-row-btn{flex-shrink:0;margin:0;margin-inline-start:auto;padding:.35rem .65rem;border-radius:.375rem;border:1px solid transparent;font:inherit;font-size:.8rem;font-weight:600;letter-spacing:.01em;line-height:1.2;cursor:pointer;white-space:nowrap;transition:transform .2s ease}.toast-row-btn:focus-visible{outline:2px solid var(--toast-color);outline-offset:2px}.toast-row-btn:active{transform:scale(.95)}.action-btn{background:var(--toast-action-bg);color:var(--toast-action-text);border-color:var(--toast-action-border)}.cancel-btn{background:var(--toast-cancel-bg);color:var(--toast-color);border-color:var(--toast-cancel-border)}.toast-custom{flex:1;min-width:0;width:100%;font-size:.825rem;font-weight:400;line-height:calc(1.25 / .875)}.toast-custom :first-child{margin-top:0}.toast-custom :last-child{margin-bottom:0}.close-btn{position:absolute;top:-.3875rem;right:-.3875rem;flex-shrink:0;margin:-.15rem -.25rem -.15rem 0;border:1px solid var(--_chrome-border);box-shadow:var(--toast-shadow);background:var(--_chrome-bg);color:var(--_chrome-fg);cursor:pointer;line-height:1;padding:.25rem;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;opacity:1;scale:1;filter:blur(0)}.close-btn.close-enter{opacity:1;scale:1;filter:blur(0);transition:opacity .18s cubic-bezier(.19,1,.22,1),scale .18s cubic-bezier(.19,1,.22,1),filter .18s cubic-bezier(.19,1,.22,1)}@starting-style{.close-btn.close-enter{opacity:0;scale:.92;filter:blur(4px)}}.close-btn.close-leave{opacity:0;scale:.92;filter:blur(4px);pointer-events:none;transition:opacity .15s cubic-bezier(.19,1,.22,1),scale .15s cubic-bezier(.19,1,.22,1),filter .15s cubic-bezier(.19,1,.22,1)}.close-btn:focus-visible{outline:2px solid currentColor}.close-btn svg{display:block;width:.825rem;height:.825rem}:host(.leave){opacity:0;scale:.95;transform:translate(var(--_toast-x)) translateY(var(--_toast-leave-y))}@media(prefers-reduced-motion:reduce){:host{transition:none}:host([data-position]){--_toast-enter-y: var(--_toast-y);--_toast-leave-y: var(--_toast-y)}:host>*{transition:none}:host(.leave){scale:1}.toast-row-btn:active{transform:none}.close-btn.close-enter{scale:1;filter:none;transition:opacity .15s ease}@starting-style{.close-btn.close-enter{opacity:0;scale:1;filter:none}}.close-btn.close-leave{scale:1;filter:none;transition:opacity .15s ease}.toast-icon-loading{animation:none}}\n"] }]
1192
+ }], ctorParameters: () => [], propDecorators: { toast: [{ type: i0.Input, args: [{ isSignal: true, alias: "toast", required: false }] }], toasterStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "toasterStyle", required: false }] }], toasterClassNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "toasterClassNames", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], closeButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButton", required: false }] }], customIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "customIcons", required: false }] }], dismissButtonAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissButtonAriaLabel", required: false }] }], stackPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "stackPosition", required: false }] }], stackExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "stackExpanded", required: false }] }], stackFront: [{ type: i0.Input, args: [{ isSignal: true, alias: "stackFront", required: false }] }], stackHover: [{ type: i0.Output, args: ["stackHover"] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], heightChange: [{ type: i0.Output, args: ["heightChange"] }] } });
1097
1193
  /**
1098
1194
  * Renders the toaster stack. Add once near the root of your app (e.g. in `App`).
1195
+ * With `[stacked]="true"` (default), extra toasts collapse into a 3-layer card stack (latest in front); hover, focus, or a press on touch expands the full list.
1196
+ * Set `[stacked]="false"` to keep every toast fully visible, spaced by height plus gap.
1099
1197
  * Variant-colored surfaces are off by default; set `[richColors]="true"` to enable them.
1100
1198
  * Set `[duration]` for auto-dismiss when service helpers omit their duration argument.
1101
1199
  * Use **`duration="Infinity"`** (that exact literal) or `[duration]="…"` with a number / {@link TOAST_DURATION_MANUAL_DISMISS} for persist until dismissed; `0` still works.
@@ -1122,26 +1220,37 @@ class BetterToaster {
1122
1220
  return durationMs;
1123
1221
  } });
1124
1222
  /** Where the stack is anchored on the viewport. */
1125
- position = input('bottom-right', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1223
+ position = input('bottom-right', /* @ts-ignore */
1224
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1225
+ /**
1226
+ * When true (default), extra toasts collapse into a 3-layer card stack; hover, focus, or a press on touch expands the list.
1227
+ * When false, every toast stays fully visible, spaced by measured height plus gap.
1228
+ */
1229
+ stacked = input(true, /* @ts-ignore */
1230
+ ...(ngDevMode ? [{ debugName: "stacked" }] : /* istanbul ignore next */ []));
1126
1231
  /**
1127
1232
  * Viewport inset for the toast stack: a single CSS value for all sides, or an object with any of `top` / `right` / `bottom` / `left`.
1128
1233
  * Binds `--toast-offset-top` / `right` / `bottom` / `left` on `.toast-container`.
1129
1234
  */
1130
- offset = input(undefined, ...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
1235
+ offset = input(undefined, /* @ts-ignore */
1236
+ ...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
1131
1237
  /**
1132
1238
  * Viewport inset for narrow layouts: binds `--toast-offset-mobile-top` / `right` / `bottom` / `left` on `.toast-container`.
1133
1239
  * Same shape as {@link offset}.
1134
1240
  */
1135
- mobileOffset = input(undefined, ...(ngDevMode ? [{ debugName: "mobileOffset" }] : /* istanbul ignore next */ []));
1241
+ mobileOffset = input(undefined, /* @ts-ignore */
1242
+ ...(ngDevMode ? [{ debugName: "mobileOffset" }] : /* istanbul ignore next */ []));
1136
1243
  /**
1137
1244
  * When true, success/error/info/warning use semantic background and border colors.
1138
1245
  */
1139
- richColors = input(false, ...(ngDevMode ? [{ debugName: "richColors" }] : /* istanbul ignore next */ []));
1246
+ richColors = input(false, /* @ts-ignore */
1247
+ ...(ngDevMode ? [{ debugName: "richColors" }] : /* istanbul ignore next */ []));
1140
1248
  /**
1141
1249
  * Color palette for the stack. `system` (default) follows `prefers-color-scheme`; `light` / `dark` pin the palette regardless of OS.
1142
1250
  * Reflected as `data-theme` on the toast container (`<ol class="toast-container">`).
1143
1251
  */
1144
- theme = input('system', ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
1252
+ theme = input('system', /* @ts-ignore */
1253
+ ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
1145
1254
  /**
1146
1255
  * Optional per-variant **standalone** components that replace the default SVG (or loading indicator).
1147
1256
  * Import each icon component in the host and pass its class here; each one should render an SVG
@@ -1149,48 +1258,100 @@ class BetterToaster {
1149
1258
  * Omitted keys keep the built-in icons (the `default` variant has none unless you set `default` here).
1150
1259
  * **`null`** for a variant hides that variant’s icon.
1151
1260
  */
1152
- icons = input(...(ngDevMode ? [undefined, { debugName: "icons" }] : /* istanbul ignore next */ []));
1261
+ icons = input(/* @ts-ignore */
1262
+ ...(ngDevMode ? [undefined, { debugName: "icons" }] : /* istanbul ignore next */ []));
1153
1263
  /**
1154
1264
  * Defaults for every toast — shape is {@link ToasterToastOptions}.
1155
1265
  *
1156
1266
  * - **`style`** — merged onto each toast host with per-toast {@link ToastOptions.style}; identical keys from the service call win.
1157
1267
  * - **`classNames`** — extra classes on host / `.msg` / `.description` / `.close-btn` / row buttons via **`[class]`**; see {@link ToasterToastOptions.classNames} (**`!important`** is usually required for overrides). Per-toast {@link ToastOptions.classNames} replaces host/message/close keys; row overrides come from {@link ToasterService.action} / {@link ToasterService.cancel}.
1158
1268
  */
1159
- toastOptions = input(...(ngDevMode ? [undefined, { debugName: "toastOptions" }] : /* istanbul ignore next */ []));
1269
+ toastOptions = input(/* @ts-ignore */
1270
+ ...(ngDevMode ? [undefined, { debugName: "toastOptions" }] : /* istanbul ignore next */ []));
1160
1271
  /** When true, each toast shows a dismiss button. */
1161
- closeButton = input(true, ...(ngDevMode ? [{ debugName: "closeButton" }] : /* istanbul ignore next */ []));
1272
+ closeButton = input(true, /* @ts-ignore */
1273
+ ...(ngDevMode ? [{ debugName: "closeButton" }] : /* istanbul ignore next */ []));
1162
1274
  /**
1163
1275
  * Overrides for built-in English `aria-label` values (live region and per-toast dismiss).
1164
1276
  * Omitted keys keep {@link DEFAULT_TOASTER_ARIA_NOTIFICATIONS_REGION} and {@link DEFAULT_TOASTER_ARIA_DISMISS_BUTTON}.
1165
1277
  */
1166
- accessibilityLabels = input(...(ngDevMode ? [undefined, { debugName: "accessibilityLabels" }] : /* istanbul ignore next */ []));
1278
+ accessibilityLabels = input(/* @ts-ignore */
1279
+ ...(ngDevMode ? [undefined, { debugName: "accessibilityLabels" }] : /* istanbul ignore next */ []));
1167
1280
  /** Measured height in px per toast id, updated when a toast item reports `heightChange`. */
1168
- heights = signal({}, ...(ngDevMode ? [{ debugName: "heights" }] : /* istanbul ignore next */ []));
1281
+ heights = signal({}, /* @ts-ignore */
1282
+ ...(ngDevMode ? [{ debugName: "heights" }] : /* istanbul ignore next */ []));
1283
+ /** Gap between expanded toasts; kept in sync with layout math and the CSS hit-area. */
1284
+ stackGapPx = GAP;
1285
+ /** Height of the newest measured toast, used so collapsed layers share one silhouette. */
1286
+ frontToastHeightCss = computed(() => {
1287
+ const height = resolveFrontToastHeightPx(this.toaster.toasts(), this.heights());
1288
+ return height ? `${height}px` : null;
1289
+ }, /* @ts-ignore */
1290
+ ...(ngDevMode ? [{ debugName: "frontToastHeightCss" }] : /* istanbul ignore next */ []));
1291
+ /** Pointer is over a toast (or moving between toasts in the stack). */
1292
+ hovering = signal(false, /* @ts-ignore */
1293
+ ...(ngDevMode ? [{ debugName: "hovering" }] : /* istanbul ignore next */ []));
1294
+ /** Keyboard focus is inside the toast list. */
1295
+ focusWithin = signal(false, /* @ts-ignore */
1296
+ ...(ngDevMode ? [{ debugName: "focusWithin" }] : /* istanbul ignore next */ []));
1297
+ /** Hover or focus: expands a stacked list and pauses auto-dismiss. */
1298
+ expanded = computed(() => this.hovering() || this.focusWithin(), /* @ts-ignore */
1299
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
1300
+ /** Layout uses the expanded list while stacked is off, or while the stack is hovered / focused. */
1301
+ layoutExpanded = computed(() => !this.stacked() || this.expanded(), /* @ts-ignore */
1302
+ ...(ngDevMode ? [{ debugName: "layoutExpanded" }] : /* istanbul ignore next */ []));
1303
+ constructor() {
1304
+ effect(() => {
1305
+ if (this.toaster.toasts().length === 0) {
1306
+ this.hovering.set(false);
1307
+ this.focusWithin.set(false);
1308
+ }
1309
+ });
1310
+ effect(() => {
1311
+ if (!this.expanded()) {
1312
+ return;
1313
+ }
1314
+ for (const toast of this.toaster.toasts()) {
1315
+ this.toaster.pauseAutoDismiss(toast.id);
1316
+ }
1317
+ });
1318
+ }
1169
1319
  /** Resolved `aria-label` for the outer `<section>` live region. */
1170
- notificationsRegionAriaLabel = computed(() => this.accessibilityLabels()?.notificationsRegion ?? DEFAULT_TOASTER_ARIA_NOTIFICATIONS_REGION, ...(ngDevMode ? [{ debugName: "notificationsRegionAriaLabel" }] : /* istanbul ignore next */ []));
1320
+ notificationsRegionAriaLabel = computed(() => this.accessibilityLabels()?.notificationsRegion ?? DEFAULT_TOASTER_ARIA_NOTIFICATIONS_REGION, /* @ts-ignore */
1321
+ ...(ngDevMode ? [{ debugName: "notificationsRegionAriaLabel" }] : /* istanbul ignore next */ []));
1171
1322
  /** Resolved `aria-label` for each toast’s dismiss control. */
1172
- dismissButtonAriaLabel = computed(() => this.accessibilityLabels()?.dismissButton ?? DEFAULT_TOASTER_ARIA_DISMISS_BUTTON, ...(ngDevMode ? [{ debugName: "dismissButtonAriaLabel" }] : /* istanbul ignore next */ []));
1323
+ dismissButtonAriaLabel = computed(() => this.accessibilityLabels()?.dismissButton ?? DEFAULT_TOASTER_ARIA_DISMISS_BUTTON, /* @ts-ignore */
1324
+ ...(ngDevMode ? [{ debugName: "dismissButtonAriaLabel" }] : /* istanbul ignore next */ []));
1173
1325
  /** Vertical offset in px for the toast stack. */
1174
- offsetTop = computed(() => resolveToasterOffsetSide(this.offset(), 'top'), ...(ngDevMode ? [{ debugName: "offsetTop" }] : /* istanbul ignore next */ []));
1326
+ offsetTop = computed(() => resolveToasterOffsetSide(this.offset(), 'top'), /* @ts-ignore */
1327
+ ...(ngDevMode ? [{ debugName: "offsetTop" }] : /* istanbul ignore next */ []));
1175
1328
  /** Horizontal offset in px for the toast stack. */
1176
- offsetRight = computed(() => resolveToasterOffsetSide(this.offset(), 'right'), ...(ngDevMode ? [{ debugName: "offsetRight" }] : /* istanbul ignore next */ []));
1329
+ offsetRight = computed(() => resolveToasterOffsetSide(this.offset(), 'right'), /* @ts-ignore */
1330
+ ...(ngDevMode ? [{ debugName: "offsetRight" }] : /* istanbul ignore next */ []));
1177
1331
  /** Vertical offset in px for the toast stack. */
1178
- offsetBottom = computed(() => resolveToasterOffsetSide(this.offset(), 'bottom'), ...(ngDevMode ? [{ debugName: "offsetBottom" }] : /* istanbul ignore next */ []));
1332
+ offsetBottom = computed(() => resolveToasterOffsetSide(this.offset(), 'bottom'), /* @ts-ignore */
1333
+ ...(ngDevMode ? [{ debugName: "offsetBottom" }] : /* istanbul ignore next */ []));
1179
1334
  /** Horizontal offset in px for the toast stack. */
1180
- offsetLeft = computed(() => resolveToasterOffsetSide(this.offset(), 'left'), ...(ngDevMode ? [{ debugName: "offsetLeft" }] : /* istanbul ignore next */ []));
1335
+ offsetLeft = computed(() => resolveToasterOffsetSide(this.offset(), 'left'), /* @ts-ignore */
1336
+ ...(ngDevMode ? [{ debugName: "offsetLeft" }] : /* istanbul ignore next */ []));
1181
1337
  /** Vertical offset in px for the toast stack on narrow layouts. */
1182
- mobileOffsetTop = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'top'), ...(ngDevMode ? [{ debugName: "mobileOffsetTop" }] : /* istanbul ignore next */ []));
1338
+ mobileOffsetTop = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'top'), /* @ts-ignore */
1339
+ ...(ngDevMode ? [{ debugName: "mobileOffsetTop" }] : /* istanbul ignore next */ []));
1183
1340
  /** Horizontal offset in px for the toast stack on narrow layouts. */
1184
- mobileOffsetRight = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'right'), ...(ngDevMode ? [{ debugName: "mobileOffsetRight" }] : /* istanbul ignore next */ []));
1341
+ mobileOffsetRight = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'right'), /* @ts-ignore */
1342
+ ...(ngDevMode ? [{ debugName: "mobileOffsetRight" }] : /* istanbul ignore next */ []));
1185
1343
  /** Vertical offset in px for the toast stack on narrow layouts. */
1186
- mobileOffsetBottom = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'bottom'), ...(ngDevMode ? [{ debugName: "mobileOffsetBottom" }] : /* istanbul ignore next */ []));
1344
+ mobileOffsetBottom = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'bottom'), /* @ts-ignore */
1345
+ ...(ngDevMode ? [{ debugName: "mobileOffsetBottom" }] : /* istanbul ignore next */ []));
1187
1346
  /** Horizontal offset in px for the toast stack on narrow layouts. */
1188
- mobileOffsetLeft = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'left'), ...(ngDevMode ? [{ debugName: "mobileOffsetLeft" }] : /* istanbul ignore next */ []));
1347
+ mobileOffsetLeft = computed(() => resolveToasterOffsetSide(this.mobileOffset(), 'left'), /* @ts-ignore */
1348
+ ...(ngDevMode ? [{ debugName: "mobileOffsetLeft" }] : /* istanbul ignore next */ []));
1189
1349
  /**
1190
- * Vertical offset in px for each toast id so stacked toasts do not overlap.
1191
- * Walks newest-to-oldest (end of the list first): the latest toast has offset 0; each older toast sits above by the sum of heights below plus the inter-toast gap.
1350
+ * `--index` is the stack depth: last item is 0 (front), older items count up.
1351
+ * Collapsed peek, scale, front, and hidden layers are CSS from that index / `:last-child`.
1352
+ * Expanded offset still needs measured heights: each toast sits at the sum of those in front plus gap.
1192
1353
  */
1193
- offsets = computed(() => {
1354
+ expandedOffsets = computed(() => {
1194
1355
  const toastsList = this.toaster.toasts();
1195
1356
  const heights = this.heights();
1196
1357
  const result = {};
@@ -1201,110 +1362,217 @@ class BetterToaster {
1201
1362
  cumulative += (heights[toast.id] ?? 0) + GAP;
1202
1363
  }
1203
1364
  return result;
1204
- }, ...(ngDevMode ? [{ debugName: "offsets" }] : /* istanbul ignore next */ []));
1205
- /** Merges a toast item’s reported height into `heights` so `offsets` can recompute. */
1365
+ }, /* @ts-ignore */
1366
+ ...(ngDevMode ? [{ debugName: "expandedOffsets" }] : /* istanbul ignore next */ []));
1367
+ /** Oldest toasts past the 3 visible collapsed layers. */
1368
+ hiddenToastIds = computed(() => {
1369
+ if (this.layoutExpanded()) {
1370
+ return new Set();
1371
+ }
1372
+ const toasts = this.toaster.toasts();
1373
+ const hidden = new Set();
1374
+ const cutoff = toasts.length - VISIBLE_TOASTS;
1375
+ for (let i = 0; i < cutoff; i++) {
1376
+ hidden.add(toasts[i].id);
1377
+ }
1378
+ return hidden;
1379
+ }, /* @ts-ignore */
1380
+ ...(ngDevMode ? [{ debugName: "hiddenToastIds" }] : /* istanbul ignore next */ []));
1381
+ /** Expanded stack only: measured height + gap. Collapsed `--offset` comes from `--index` in CSS. */
1382
+ toastOffsetCss(toastId) {
1383
+ if (!this.layoutExpanded()) {
1384
+ return null;
1385
+ }
1386
+ return `${this.expandedOffsets()[toastId] ?? 0}px`;
1387
+ }
1388
+ /** Merges a toast item’s reported height into `heights` so expanded offsets can recompute. */
1206
1389
  onHeightChange(toastId, height) {
1207
1390
  this.heights.update((h) => ({ ...h, [toastId]: height }));
1208
1391
  }
1392
+ /** Expands the stack and pauses auto-dismiss while the pointer is over any toast. */
1393
+ onItemStackHover(hovering) {
1394
+ this.hovering.set(hovering);
1395
+ if (hovering || this.focusWithin()) {
1396
+ this.pauseAllAutoDismiss();
1397
+ }
1398
+ else {
1399
+ this.resumeAllAutoDismiss();
1400
+ }
1401
+ }
1402
+ /**
1403
+ * Collapses a touch/pen sticky expand when the next press is outside the stack.
1404
+ * Hover pointers already collapse on `pointerleave`.
1405
+ */
1406
+ onDocumentPointerDown(event) {
1407
+ if (!this.hovering() || isInsideToastItem(event.target)) {
1408
+ return;
1409
+ }
1410
+ this.hovering.set(false);
1411
+ if (!this.focusWithin()) {
1412
+ this.resumeAllAutoDismiss();
1413
+ }
1414
+ }
1415
+ /** Expands the stack when a toast (or dismiss control) receives keyboard focus. */
1416
+ onStackFocusIn(event) {
1417
+ if (!isInsideToastItem(event.target)) {
1418
+ if (event.target instanceof HTMLElement) {
1419
+ event.target.blur();
1420
+ }
1421
+ return;
1422
+ }
1423
+ this.focusWithin.set(true);
1424
+ this.pauseAllAutoDismiss();
1425
+ }
1426
+ /** Collapses when focus leaves the list, unless the pointer is still over it. */
1427
+ onStackFocusOut(event) {
1428
+ const next = event.relatedTarget;
1429
+ if (isInsideToastItem(next)) {
1430
+ return;
1431
+ }
1432
+ this.focusWithin.set(false);
1433
+ if (!this.hovering()) {
1434
+ this.resumeAllAutoDismiss();
1435
+ }
1436
+ }
1437
+ pauseAllAutoDismiss() {
1438
+ for (const toast of this.toaster.toasts()) {
1439
+ this.toaster.pauseAutoDismiss(toast.id);
1440
+ }
1441
+ }
1442
+ resumeAllAutoDismiss() {
1443
+ for (const toast of this.toaster.toasts()) {
1444
+ this.toaster.resumeAutoDismiss(toast.id);
1445
+ }
1446
+ }
1209
1447
  /**
1210
1448
  * Initializes the toaster service with the default duration.
1211
1449
  */
1212
1450
  ngOnInit() {
1213
1451
  this.toaster.setDefaultDurationMs(this.durationMs());
1214
1452
  }
1215
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BetterToaster, deps: [], target: i0.ɵɵFactoryTarget.Component });
1216
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BetterToaster, isStandalone: true, selector: "better-toaster", inputs: { durationMs: { classPropertyName: "durationMs", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, mobileOffset: { classPropertyName: "mobileOffset", publicName: "mobileOffset", isSignal: true, isRequired: false, transformFunction: null }, richColors: { classPropertyName: "richColors", publicName: "richColors", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, icons: { classPropertyName: "icons", publicName: "icons", isSignal: true, isRequired: false, transformFunction: null }, toastOptions: { classPropertyName: "toastOptions", publicName: "toastOptions", isSignal: true, isRequired: false, transformFunction: null }, closeButton: { classPropertyName: "closeButton", publicName: "closeButton", isSignal: true, isRequired: false, transformFunction: null }, accessibilityLabels: { classPropertyName: "accessibilityLabels", publicName: "accessibilityLabels", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1217
- <section
1218
- [attr.aria-label]="notificationsRegionAriaLabel()"
1219
- tabindex="-1"
1220
- aria-live="polite"
1221
- aria-relevant="additions text"
1222
- aria-atomic="false"
1223
- >
1224
- <ol
1225
- class="toast-container"
1226
- [style.--toast-offset-top]="offsetTop()"
1227
- [style.--toast-offset-right]="offsetRight()"
1228
- [style.--toast-offset-bottom]="offsetBottom()"
1229
- [style.--toast-offset-left]="offsetLeft()"
1230
- [style.--toast-offset-mobile-top]="mobileOffsetTop()"
1231
- [style.--toast-offset-mobile-right]="mobileOffsetRight()"
1232
- [style.--toast-offset-mobile-bottom]="mobileOffsetBottom()"
1233
- [style.--toast-offset-mobile-left]="mobileOffsetLeft()"
1234
- [attr.data-position]="position()"
1235
- [attr.data-rich-colors]="richColors()"
1236
- [attr.data-theme]="theme()"
1237
- tabindex="-1"
1238
- >
1239
- @for (toast of toaster.toasts(); track toast.id) {
1240
- <li
1241
- betterToastItem
1242
- [toast]="toast"
1243
- [toasterStyle]="toastOptions()?.style"
1244
- [toasterClassNames]="toastOptions()?.classNames"
1245
- [variant]="toast.variant"
1246
- [customIcons]="icons()"
1247
- [offset]="offsets()[toast.id]"
1248
- [closeButton]="closeButton()"
1249
- [dismissButtonAriaLabel]="dismissButtonAriaLabel()"
1250
- [stackPosition]="position()"
1251
- [theme]="theme()"
1252
- (heightChange)="onHeightChange(toast.id, $event)"
1253
- [attr.data-position]="position()"
1254
- [attr.data-rich-colors]="richColors()"
1255
- ></li>
1256
- }
1257
- </ol>
1258
- </section>
1259
- `, isInline: true, styles: [":host{--toast-width: 356px;--toast-gap: 1rem;--toast-z-index: 99999;--toast-offset-top: 24px;--toast-offset-bottom: 24px;--toast-offset-left: 24px;--toast-offset-right: 24px;--toast-offset-mobile-top: 16px;--toast-offset-mobile-bottom: 16px;--toast-offset-mobile-left: 16px;--toast-offset-mobile-right: 16px}.toast-container[data-theme=light]{color-scheme:light}.toast-container[data-theme=dark]{color-scheme:dark}.toast-container[data-theme=system]{color-scheme:light dark}.toast-container{--toast-bg: light-dark(oklch(100% 0 0), oklch(10% 0 0));--toast-color: light-dark(oklch(30% 0 0), oklch(98% 0 0));--toast-border-color: light-dark(hsl(0, 0%, 93%), hsl(0, 0%, 20%));--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1);--toast-success-bg: light-dark(oklch(97.9% .021 166.113), oklch(26.2% .051 172.552));--toast-success-text: light-dark(oklch(59.6% .145 163.225), oklch(92.5% .084 155.995));--toast-success-border: light-dark( oklch(69.6% .17 162.48 / .1), oklch(92.5% .084 155.995 / .1) );--toast-error-bg: light-dark(oklch(97.5% .012 25), oklch(25.8% .092 26.042));--toast-error-text: light-dark(oklch(57.7% .245 27.325), oklch(88.5% .062 18.334));--toast-error-border: light-dark( oklch(80.8% .114 19.571 / .1), oklch(88.5% .062 18.334 / .125) );--toast-info-bg: light-dark(oklch(97.7% .013 236.62), oklch(29.3% .066 243.157));--toast-info-text: light-dark(oklch(68.5% .169 237.323), oklch(90.1% .058 230.902));--toast-info-border: light-dark( oklch(82.8% .111 230.318 / .15), oklch(90.1% .058 230.902 / .125) );--toast-warning-bg: light-dark(oklch(98.7% .022 95.277), oklch(28.6% .066 53.813));--toast-warning-text: light-dark(oklch(66.6% .179 58.318), oklch(92.4% .12 95.746));--toast-warning-border: light-dark( oklch(76.9% .188 70.08 / .15), oklch(92.4% .12 95.746 / .125) );--toast-action-bg: light-dark(var(--color-black), var(--color-white));--toast-action-text: light-dark(var(--color-white), var(--color-black));--toast-action-border: light-dark(var(--color-black), var(--color-white));--toast-cancel-bg: light-dark(oklch(86.9% .005 56.366 / .3), oklch(26.8% .007 34.298 / .85));--toast-cancel-text: var(--toast-color);--toast-cancel-border: light-dark( oklch(86.9% .005 56.366 / .1), oklch(26.8% .007 34.298 / .5) );position:fixed;z-index:var(--toast-z-index);width:auto;pointer-events:none;overflow:visible;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.toast-container[data-theme=dark]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}@media(prefers-color-scheme:dark){.toast-container[data-theme=system]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}}.toast-container[data-position^=top]{top:var(--toast-offset-mobile-top);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}.toast-container[data-position^=bottom]{bottom:var(--toast-offset-mobile-bottom);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}@media(width>=40rem){.toast-container{width:var(--toast-width)}.toast-container[data-position=top-left]{top:var(--toast-offset-top);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=top-center]{top:var(--toast-offset-top);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=top-right]{top:var(--toast-offset-top);right:var(--toast-offset-right);left:auto;align-items:flex-end}.toast-container[data-position=bottom-left]{bottom:var(--toast-offset-bottom);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=bottom-center]{bottom:var(--toast-offset-bottom);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=bottom-right]{bottom:var(--toast-offset-bottom);right:var(--toast-offset-right);left:auto;align-items:flex-end}}\n"], dependencies: [{ kind: "component", type: BetterToastItem, selector: "li[betterToastItem]", inputs: ["toast", "toasterStyle", "toasterClassNames", "variant", "offset", "closeButton", "customIcons", "dismissButtonAriaLabel", "stackPosition", "theme"], outputs: ["heightChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1453
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: BetterToaster, deps: [], target: i0.ɵɵFactoryTarget.Component });
1454
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: BetterToaster, isStandalone: true, selector: "better-toaster", inputs: { durationMs: { classPropertyName: "durationMs", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, stacked: { classPropertyName: "stacked", publicName: "stacked", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, mobileOffset: { classPropertyName: "mobileOffset", publicName: "mobileOffset", isSignal: true, isRequired: false, transformFunction: null }, richColors: { classPropertyName: "richColors", publicName: "richColors", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, icons: { classPropertyName: "icons", publicName: "icons", isSignal: true, isRequired: false, transformFunction: null }, toastOptions: { classPropertyName: "toastOptions", publicName: "toastOptions", isSignal: true, isRequired: false, transformFunction: null }, closeButton: { classPropertyName: "closeButton", publicName: "closeButton", isSignal: true, isRequired: false, transformFunction: null }, accessibilityLabels: { classPropertyName: "accessibilityLabels", publicName: "accessibilityLabels", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)" } }, ngImport: i0, template: `
1455
+ <section
1456
+ [attr.aria-label]="notificationsRegionAriaLabel()"
1457
+ tabindex="-1"
1458
+ aria-live="polite"
1459
+ aria-relevant="additions text"
1460
+ aria-atomic="false"
1461
+ >
1462
+ <ol
1463
+ class="toast-container"
1464
+ [style.--toast-offset-top]="offsetTop()"
1465
+ [style.--toast-offset-right]="offsetRight()"
1466
+ [style.--toast-offset-bottom]="offsetBottom()"
1467
+ [style.--toast-offset-left]="offsetLeft()"
1468
+ [style.--toast-offset-mobile-top]="mobileOffsetTop()"
1469
+ [style.--toast-offset-mobile-right]="mobileOffsetRight()"
1470
+ [style.--toast-offset-mobile-bottom]="mobileOffsetBottom()"
1471
+ [style.--toast-offset-mobile-left]="mobileOffsetLeft()"
1472
+ [style.--toast-gap]="stackGapPx + 'px'"
1473
+ [style.--front-toast-height]="frontToastHeightCss()"
1474
+ [attr.data-position]="position()"
1475
+ [attr.data-rich-colors]="richColors()"
1476
+ [attr.data-theme]="theme()"
1477
+ [attr.data-stacked]="stacked() ? 'true' : 'false'"
1478
+ [attr.data-expanded]="layoutExpanded() ? 'true' : 'false'"
1479
+ tabindex="-1"
1480
+ (focusin)="onStackFocusIn($event)"
1481
+ (focusout)="onStackFocusOut($event)"
1482
+ >
1483
+ @for (toast of toaster.toasts(); track toast.id) {
1484
+ <li
1485
+ betterToastItem
1486
+ [toast]="toast"
1487
+ [toasterStyle]="toastOptions()?.style"
1488
+ [toasterClassNames]="toastOptions()?.classNames"
1489
+ [variant]="toast.variant"
1490
+ [customIcons]="icons()"
1491
+ [closeButton]="closeButton()"
1492
+ [dismissButtonAriaLabel]="dismissButtonAriaLabel()"
1493
+ [stackPosition]="position()"
1494
+ [stackExpanded]="layoutExpanded()"
1495
+ [stackFront]="$last"
1496
+ [theme]="theme()"
1497
+ (heightChange)="onHeightChange(toast.id, $event)"
1498
+ (stackHover)="onItemStackHover($event)"
1499
+ [style.--index]="$count - 1 - $index"
1500
+ [style.--offset]="toastOffsetCss(toast.id)"
1501
+ [attr.data-position]="position()"
1502
+ [attr.data-rich-colors]="richColors()"
1503
+ [attr.data-expanded]="layoutExpanded() ? 'true' : 'false'"
1504
+ [attr.data-front]="$last ? 'true' : null"
1505
+ [attr.aria-hidden]="hiddenToastIds().has(toast.id) ? 'true' : null"
1506
+ [attr.inert]="hiddenToastIds().has(toast.id) ? true : null"
1507
+ ></li>
1508
+ }
1509
+ </ol>
1510
+ </section>
1511
+ `, isInline: true, styles: [":host{--toast-width: 356px;--toast-gap: 16px;--toast-z-index: 99999;--toast-offset-top: 24px;--toast-offset-bottom: 24px;--toast-offset-left: 24px;--toast-offset-right: 24px;--toast-offset-mobile-top: 16px;--toast-offset-mobile-bottom: 16px;--toast-offset-mobile-left: 16px;--toast-offset-mobile-right: 16px}.toast-container[data-theme=light]{color-scheme:light}.toast-container[data-theme=dark]{color-scheme:dark}.toast-container[data-theme=system]{color-scheme:light dark}.toast-container{--toast-bg: light-dark(oklch(100% 0 0), oklch(10% 0 0));--toast-color: light-dark(oklch(30% 0 0), oklch(98% 0 0));--toast-border-color: light-dark(hsl(0, 0%, 93%), hsl(0, 0%, 20%));--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1);--toast-success-bg: light-dark(oklch(97.9% .021 166.113), oklch(26.2% .051 172.552));--toast-success-text: light-dark(oklch(59.6% .145 163.225), oklch(92.5% .084 155.995));--toast-success-border: light-dark( oklch(69.6% .17 162.48 / .1), oklch(92.5% .084 155.995 / .1) );--toast-error-bg: light-dark(oklch(97.5% .012 25), oklch(25.8% .092 26.042));--toast-error-text: light-dark(oklch(57.7% .245 27.325), oklch(88.5% .062 18.334));--toast-error-border: light-dark( oklch(80.8% .114 19.571 / .1), oklch(88.5% .062 18.334 / .125) );--toast-info-bg: light-dark(oklch(97.7% .013 236.62), oklch(29.3% .066 243.157));--toast-info-text: light-dark(oklch(68.5% .169 237.323), oklch(90.1% .058 230.902));--toast-info-border: light-dark( oklch(82.8% .111 230.318 / .15), oklch(90.1% .058 230.902 / .125) );--toast-warning-bg: light-dark(oklch(98.7% .022 95.277), oklch(28.6% .066 53.813));--toast-warning-text: light-dark(oklch(66.6% .179 58.318), oklch(92.4% .12 95.746));--toast-warning-border: light-dark( oklch(76.9% .188 70.08 / .15), oklch(92.4% .12 95.746 / .125) );--toast-action-bg: light-dark(var(--color-black), var(--color-white));--toast-action-text: light-dark(var(--color-white), var(--color-black));--toast-action-border: light-dark(var(--color-black), var(--color-white));--toast-cancel-bg: light-dark(oklch(86.9% .005 56.366 / .3), oklch(26.8% .007 34.298 / .85));--toast-cancel-text: var(--toast-color);--toast-cancel-border: light-dark( oklch(86.9% .005 56.366 / .1), oklch(26.8% .007 34.298 / .5) );position:fixed;z-index:var(--toast-z-index);width:auto;pointer-events:none;overflow:visible;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.toast-container[data-theme=dark]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}@media(prefers-color-scheme:dark){.toast-container[data-theme=system]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}}.toast-container[data-position^=top]{top:var(--toast-offset-mobile-top);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}.toast-container[data-position^=bottom]{bottom:var(--toast-offset-mobile-bottom);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}@media(width>=40rem){.toast-container{width:var(--toast-width)}.toast-container[data-position=top-left]{top:var(--toast-offset-top);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=top-center]{top:var(--toast-offset-top);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=top-right]{top:var(--toast-offset-top);right:var(--toast-offset-right);left:auto;align-items:flex-end}.toast-container[data-position=bottom-left]{bottom:var(--toast-offset-bottom);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=bottom-center]{bottom:var(--toast-offset-bottom);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=bottom-right]{bottom:var(--toast-offset-bottom);right:var(--toast-offset-right);left:auto;align-items:flex-end}}\n"], dependencies: [{ kind: "component", type: BetterToastItem, selector: "li[betterToastItem]", inputs: ["toast", "toasterStyle", "toasterClassNames", "variant", "closeButton", "customIcons", "dismissButtonAriaLabel", "stackPosition", "stackExpanded", "stackFront", "theme"], outputs: ["stackHover", "heightChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1260
1512
  }
1261
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BetterToaster, decorators: [{
1513
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: BetterToaster, decorators: [{
1262
1514
  type: Component,
1263
- args: [{ selector: 'better-toaster', changeDetection: ChangeDetectionStrategy.OnPush, imports: [BetterToastItem], template: `
1264
- <section
1265
- [attr.aria-label]="notificationsRegionAriaLabel()"
1266
- tabindex="-1"
1267
- aria-live="polite"
1268
- aria-relevant="additions text"
1269
- aria-atomic="false"
1270
- >
1271
- <ol
1272
- class="toast-container"
1273
- [style.--toast-offset-top]="offsetTop()"
1274
- [style.--toast-offset-right]="offsetRight()"
1275
- [style.--toast-offset-bottom]="offsetBottom()"
1276
- [style.--toast-offset-left]="offsetLeft()"
1277
- [style.--toast-offset-mobile-top]="mobileOffsetTop()"
1278
- [style.--toast-offset-mobile-right]="mobileOffsetRight()"
1279
- [style.--toast-offset-mobile-bottom]="mobileOffsetBottom()"
1280
- [style.--toast-offset-mobile-left]="mobileOffsetLeft()"
1281
- [attr.data-position]="position()"
1282
- [attr.data-rich-colors]="richColors()"
1283
- [attr.data-theme]="theme()"
1284
- tabindex="-1"
1285
- >
1286
- @for (toast of toaster.toasts(); track toast.id) {
1287
- <li
1288
- betterToastItem
1289
- [toast]="toast"
1290
- [toasterStyle]="toastOptions()?.style"
1291
- [toasterClassNames]="toastOptions()?.classNames"
1292
- [variant]="toast.variant"
1293
- [customIcons]="icons()"
1294
- [offset]="offsets()[toast.id]"
1295
- [closeButton]="closeButton()"
1296
- [dismissButtonAriaLabel]="dismissButtonAriaLabel()"
1297
- [stackPosition]="position()"
1298
- [theme]="theme()"
1299
- (heightChange)="onHeightChange(toast.id, $event)"
1300
- [attr.data-position]="position()"
1301
- [attr.data-rich-colors]="richColors()"
1302
- ></li>
1303
- }
1304
- </ol>
1305
- </section>
1306
- `, styles: [":host{--toast-width: 356px;--toast-gap: 1rem;--toast-z-index: 99999;--toast-offset-top: 24px;--toast-offset-bottom: 24px;--toast-offset-left: 24px;--toast-offset-right: 24px;--toast-offset-mobile-top: 16px;--toast-offset-mobile-bottom: 16px;--toast-offset-mobile-left: 16px;--toast-offset-mobile-right: 16px}.toast-container[data-theme=light]{color-scheme:light}.toast-container[data-theme=dark]{color-scheme:dark}.toast-container[data-theme=system]{color-scheme:light dark}.toast-container{--toast-bg: light-dark(oklch(100% 0 0), oklch(10% 0 0));--toast-color: light-dark(oklch(30% 0 0), oklch(98% 0 0));--toast-border-color: light-dark(hsl(0, 0%, 93%), hsl(0, 0%, 20%));--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1);--toast-success-bg: light-dark(oklch(97.9% .021 166.113), oklch(26.2% .051 172.552));--toast-success-text: light-dark(oklch(59.6% .145 163.225), oklch(92.5% .084 155.995));--toast-success-border: light-dark( oklch(69.6% .17 162.48 / .1), oklch(92.5% .084 155.995 / .1) );--toast-error-bg: light-dark(oklch(97.5% .012 25), oklch(25.8% .092 26.042));--toast-error-text: light-dark(oklch(57.7% .245 27.325), oklch(88.5% .062 18.334));--toast-error-border: light-dark( oklch(80.8% .114 19.571 / .1), oklch(88.5% .062 18.334 / .125) );--toast-info-bg: light-dark(oklch(97.7% .013 236.62), oklch(29.3% .066 243.157));--toast-info-text: light-dark(oklch(68.5% .169 237.323), oklch(90.1% .058 230.902));--toast-info-border: light-dark( oklch(82.8% .111 230.318 / .15), oklch(90.1% .058 230.902 / .125) );--toast-warning-bg: light-dark(oklch(98.7% .022 95.277), oklch(28.6% .066 53.813));--toast-warning-text: light-dark(oklch(66.6% .179 58.318), oklch(92.4% .12 95.746));--toast-warning-border: light-dark( oklch(76.9% .188 70.08 / .15), oklch(92.4% .12 95.746 / .125) );--toast-action-bg: light-dark(var(--color-black), var(--color-white));--toast-action-text: light-dark(var(--color-white), var(--color-black));--toast-action-border: light-dark(var(--color-black), var(--color-white));--toast-cancel-bg: light-dark(oklch(86.9% .005 56.366 / .3), oklch(26.8% .007 34.298 / .85));--toast-cancel-text: var(--toast-color);--toast-cancel-border: light-dark( oklch(86.9% .005 56.366 / .1), oklch(26.8% .007 34.298 / .5) );position:fixed;z-index:var(--toast-z-index);width:auto;pointer-events:none;overflow:visible;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.toast-container[data-theme=dark]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}@media(prefers-color-scheme:dark){.toast-container[data-theme=system]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}}.toast-container[data-position^=top]{top:var(--toast-offset-mobile-top);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}.toast-container[data-position^=bottom]{bottom:var(--toast-offset-mobile-bottom);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}@media(width>=40rem){.toast-container{width:var(--toast-width)}.toast-container[data-position=top-left]{top:var(--toast-offset-top);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=top-center]{top:var(--toast-offset-top);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=top-right]{top:var(--toast-offset-top);right:var(--toast-offset-right);left:auto;align-items:flex-end}.toast-container[data-position=bottom-left]{bottom:var(--toast-offset-bottom);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=bottom-center]{bottom:var(--toast-offset-bottom);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=bottom-right]{bottom:var(--toast-offset-bottom);right:var(--toast-offset-right);left:auto;align-items:flex-end}}\n"] }]
1307
- }], propDecorators: { durationMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], mobileOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileOffset", required: false }] }], richColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "richColors", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], icons: [{ type: i0.Input, args: [{ isSignal: true, alias: "icons", required: false }] }], toastOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "toastOptions", required: false }] }], closeButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButton", required: false }] }], accessibilityLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "accessibilityLabels", required: false }] }] } });
1515
+ args: [{ selector: 'better-toaster', changeDetection: ChangeDetectionStrategy.OnPush, imports: [BetterToastItem], host: {
1516
+ '(document:pointerdown)': 'onDocumentPointerDown($event)',
1517
+ }, template: `
1518
+ <section
1519
+ [attr.aria-label]="notificationsRegionAriaLabel()"
1520
+ tabindex="-1"
1521
+ aria-live="polite"
1522
+ aria-relevant="additions text"
1523
+ aria-atomic="false"
1524
+ >
1525
+ <ol
1526
+ class="toast-container"
1527
+ [style.--toast-offset-top]="offsetTop()"
1528
+ [style.--toast-offset-right]="offsetRight()"
1529
+ [style.--toast-offset-bottom]="offsetBottom()"
1530
+ [style.--toast-offset-left]="offsetLeft()"
1531
+ [style.--toast-offset-mobile-top]="mobileOffsetTop()"
1532
+ [style.--toast-offset-mobile-right]="mobileOffsetRight()"
1533
+ [style.--toast-offset-mobile-bottom]="mobileOffsetBottom()"
1534
+ [style.--toast-offset-mobile-left]="mobileOffsetLeft()"
1535
+ [style.--toast-gap]="stackGapPx + 'px'"
1536
+ [style.--front-toast-height]="frontToastHeightCss()"
1537
+ [attr.data-position]="position()"
1538
+ [attr.data-rich-colors]="richColors()"
1539
+ [attr.data-theme]="theme()"
1540
+ [attr.data-stacked]="stacked() ? 'true' : 'false'"
1541
+ [attr.data-expanded]="layoutExpanded() ? 'true' : 'false'"
1542
+ tabindex="-1"
1543
+ (focusin)="onStackFocusIn($event)"
1544
+ (focusout)="onStackFocusOut($event)"
1545
+ >
1546
+ @for (toast of toaster.toasts(); track toast.id) {
1547
+ <li
1548
+ betterToastItem
1549
+ [toast]="toast"
1550
+ [toasterStyle]="toastOptions()?.style"
1551
+ [toasterClassNames]="toastOptions()?.classNames"
1552
+ [variant]="toast.variant"
1553
+ [customIcons]="icons()"
1554
+ [closeButton]="closeButton()"
1555
+ [dismissButtonAriaLabel]="dismissButtonAriaLabel()"
1556
+ [stackPosition]="position()"
1557
+ [stackExpanded]="layoutExpanded()"
1558
+ [stackFront]="$last"
1559
+ [theme]="theme()"
1560
+ (heightChange)="onHeightChange(toast.id, $event)"
1561
+ (stackHover)="onItemStackHover($event)"
1562
+ [style.--index]="$count - 1 - $index"
1563
+ [style.--offset]="toastOffsetCss(toast.id)"
1564
+ [attr.data-position]="position()"
1565
+ [attr.data-rich-colors]="richColors()"
1566
+ [attr.data-expanded]="layoutExpanded() ? 'true' : 'false'"
1567
+ [attr.data-front]="$last ? 'true' : null"
1568
+ [attr.aria-hidden]="hiddenToastIds().has(toast.id) ? 'true' : null"
1569
+ [attr.inert]="hiddenToastIds().has(toast.id) ? true : null"
1570
+ ></li>
1571
+ }
1572
+ </ol>
1573
+ </section>
1574
+ `, styles: [":host{--toast-width: 356px;--toast-gap: 16px;--toast-z-index: 99999;--toast-offset-top: 24px;--toast-offset-bottom: 24px;--toast-offset-left: 24px;--toast-offset-right: 24px;--toast-offset-mobile-top: 16px;--toast-offset-mobile-bottom: 16px;--toast-offset-mobile-left: 16px;--toast-offset-mobile-right: 16px}.toast-container[data-theme=light]{color-scheme:light}.toast-container[data-theme=dark]{color-scheme:dark}.toast-container[data-theme=system]{color-scheme:light dark}.toast-container{--toast-bg: light-dark(oklch(100% 0 0), oklch(10% 0 0));--toast-color: light-dark(oklch(30% 0 0), oklch(98% 0 0));--toast-border-color: light-dark(hsl(0, 0%, 93%), hsl(0, 0%, 20%));--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1);--toast-success-bg: light-dark(oklch(97.9% .021 166.113), oklch(26.2% .051 172.552));--toast-success-text: light-dark(oklch(59.6% .145 163.225), oklch(92.5% .084 155.995));--toast-success-border: light-dark( oklch(69.6% .17 162.48 / .1), oklch(92.5% .084 155.995 / .1) );--toast-error-bg: light-dark(oklch(97.5% .012 25), oklch(25.8% .092 26.042));--toast-error-text: light-dark(oklch(57.7% .245 27.325), oklch(88.5% .062 18.334));--toast-error-border: light-dark( oklch(80.8% .114 19.571 / .1), oklch(88.5% .062 18.334 / .125) );--toast-info-bg: light-dark(oklch(97.7% .013 236.62), oklch(29.3% .066 243.157));--toast-info-text: light-dark(oklch(68.5% .169 237.323), oklch(90.1% .058 230.902));--toast-info-border: light-dark( oklch(82.8% .111 230.318 / .15), oklch(90.1% .058 230.902 / .125) );--toast-warning-bg: light-dark(oklch(98.7% .022 95.277), oklch(28.6% .066 53.813));--toast-warning-text: light-dark(oklch(66.6% .179 58.318), oklch(92.4% .12 95.746));--toast-warning-border: light-dark( oklch(76.9% .188 70.08 / .15), oklch(92.4% .12 95.746 / .125) );--toast-action-bg: light-dark(var(--color-black), var(--color-white));--toast-action-text: light-dark(var(--color-white), var(--color-black));--toast-action-border: light-dark(var(--color-black), var(--color-white));--toast-cancel-bg: light-dark(oklch(86.9% .005 56.366 / .3), oklch(26.8% .007 34.298 / .85));--toast-cancel-text: var(--toast-color);--toast-cancel-border: light-dark( oklch(86.9% .005 56.366 / .1), oklch(26.8% .007 34.298 / .5) );position:fixed;z-index:var(--toast-z-index);width:auto;pointer-events:none;overflow:visible;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.toast-container[data-theme=dark]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}@media(prefers-color-scheme:dark){.toast-container[data-theme=system]{--toast-shadow: 0px 4px 12px rgba(0, 0, 0, .1)}}.toast-container[data-position^=top]{top:var(--toast-offset-mobile-top);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}.toast-container[data-position^=bottom]{bottom:var(--toast-offset-mobile-bottom);left:var(--toast-offset-mobile-left);right:var(--toast-offset-mobile-right)}@media(width>=40rem){.toast-container{width:var(--toast-width)}.toast-container[data-position=top-left]{top:var(--toast-offset-top);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=top-center]{top:var(--toast-offset-top);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=top-right]{top:var(--toast-offset-top);right:var(--toast-offset-right);left:auto;align-items:flex-end}.toast-container[data-position=bottom-left]{bottom:var(--toast-offset-bottom);left:var(--toast-offset-left);right:auto;align-items:flex-start}.toast-container[data-position=bottom-center]{bottom:var(--toast-offset-bottom);left:50%;transform:translate(-50%);align-items:center}.toast-container[data-position=bottom-right]{bottom:var(--toast-offset-bottom);right:var(--toast-offset-right);left:auto;align-items:flex-end}}\n"] }]
1575
+ }], ctorParameters: () => [], propDecorators: { durationMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], stacked: [{ type: i0.Input, args: [{ isSignal: true, alias: "stacked", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], mobileOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileOffset", required: false }] }], richColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "richColors", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], icons: [{ type: i0.Input, args: [{ isSignal: true, alias: "icons", required: false }] }], toastOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "toastOptions", required: false }] }], closeButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButton", required: false }] }], accessibilityLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "accessibilityLabels", required: false }] }] } });
1308
1576
 
1309
1577
  /*
1310
1578
  * Public API Surface of better-toast