import {
ChangeDetectionStrategy,
Component,
computed,
inject,
} from '@angular/core';
import { ButtonComponent } from '../button/button.component';
import { AfricaniesUiI18n } from '../i18n/africanies-ui-i18n';
import { ToastService } from './toast.service';
import type { ToastItem } from './toast.types';
import { ToastItemComponent } from './toast-item.component';
/**
* Fixed stack host attached once by {@link ToastService.ensureHost}.
* Caps to the viewport and scrolls when the stack (or an expanded group)
* would otherwise run off-screen.
*/
@Component({
selector: 'africanies-toast-host',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ToastItemComponent, ButtonComponent],
host: {
class:
'africanies-overlay-scroll pointer-events-auto block min-h-0 w-[min(calc(100%-2rem),24rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto overflow-x-hidden overscroll-contain',
role: 'region',
'[attr.aria-label]': 'notificationsAria()',
},
template: `
@if (toastService.showHostActions()) {
@if (toastService.hasStacks()) {
@if (toastService.allStacksExpanded()) {
} @else {
}
}
}
@for (toast of toasts(); track trackToast(toast)) {
}
`,
})
/**
* Fixed stack host attached once by {@link ToastService.ensureHost}. Caps to the viewport and scrolls when the stack (or an expanded group) would otherwise run off-screen.
*/
export class ToastHostComponent {
protected readonly toastService = inject(ToastService);
private readonly i18n = inject(AfricaniesUiI18n);
protected readonly toasts = this.toastService.items;
protected readonly notificationsAria = computed(() =>
this.i18n.t('africaniesUi.toast.notifications', 'Notifications'),
);
protected readonly expandAllLabel = computed(() =>
this.i18n.t('africaniesUi.toast.expandAll', 'Expand all'),
);
protected readonly collapseAllLabel = computed(() =>
this.i18n.t('africaniesUi.toast.collapseAll', 'Collapse all'),
);
protected readonly closeAllLabel = computed(() =>
this.i18n.t('africaniesUi.toast.closeAll', 'Close all'),
);
/**
* Include createdAt / count / expanded so views remount when the stack changes.
*
* @param toast - Stack entry.
* @returns Track key.
*/
protected trackToast(toast: ToastItem): string {
return `${toast.id}:${toast.createdAt}:${toast.count}:${toast.expanded}`;
}
}