Basic
Trigger a short notification from any component that can inject the service.
Icons by @ng-icons/tabler-icons
The component library does not provide icons.
Stackable notifications with variants, actions, loading states, dismissal controls, positions, and RTL support.
Preview
HTML
<ng-template #toastCloseIcon>
<ng-icon name="tablerX" />
</ng-template>
<frame-toast-viewport [closeIcon]="toastCloseIcon" />TS
import { inject } from '@angular/core';
import { FrToastModule, FrToastService } from '@frame-ui-ng/components/toast';
private readonly toast = inject(FrToastService);
notify(): void {
this.toast.show('Workspace synced', {
description: 'All local changes are now available on the server.',
});
}Trigger a short notification from any component that can inject the service.
Use semantic variants for neutral, success, info, warning, and error states.
Multiple calls layer into a compact card stack instead of replacing the previous message.
Attach one optional action for undo, retry, open, or review flows.
Create a persistent loading toast and update it when the async work completes.
Disable the close button for pinned notices and dismiss them from code.
Choose one of six viewport positions per toast.
The toast viewport inherits text direction from its surrounding container.
Override toast tokens on the viewport or a wrapping element to brand one notification region without changing service calls.
Inspect the toast surface, status marker, content stack, text, action, and close affordance. The preview renders persistent static toast markup instead of firing live page-level notifications.
The production bundle is available for review.
Toast tokens control viewport placement, stack rhythm, panel surface, text, actions, close button, variants, and motion.
SCSS
--frame-toast-viewport-inset: 1rem;
--frame-toast-viewport-width: min(100vw - 2rem, 26rem);
--frame-toast-stack-offset: 0.875rem;
--frame-toast-stack-depth: 2.25rem;
--frame-toast-stack-scale-step: 0.025;
--frame-toast-stack-expanded-gap: 0.75rem;
--frame-toast-stack-expanded-depth: 28rem;
--frame-toast-padding: 0.875rem;
--frame-toast-gap: 0.75rem;
--frame-toast-radius: var(--frame-radius-lg);
--frame-toast-bg: var(--frame-surface);
--frame-toast-color: var(--frame-foreground);
--frame-toast-border: var(--frame-border);
--frame-toast-shadow: 0 18px 45px rgb(0 0 0 / 0.14);
--frame-toast-title-font-size: 0.875rem;
--frame-toast-title-font-weight: 650;
--frame-toast-description-font-size: 0.8125rem;
--frame-toast-description-color: var(--frame-muted-foreground);
--frame-toast-status-size: 0.625rem;
--frame-toast-status-bg: var(--frame-muted-foreground);
--frame-toast-action-bg: var(--frame-primary);
--frame-toast-action-color: var(--frame-primary-foreground);
--frame-toast-action-hover-bg: color-mix(in srgb, var(--frame-primary) 88%, black);
--frame-toast-action-radius: var(--frame-radius-md);
--frame-toast-close-size: 1.75rem;
--frame-toast-close-icon-size: 1rem;
--frame-toast-close-color: var(--frame-muted-foreground);
--frame-toast-close-hover-bg: var(--frame-accent);
--frame-toast-motion-duration: 180ms;
--frame-toast-motion-easing: cubic-bezier(0.16, 1, 0.3, 1);
--frame-toast-stack-transition-duration: 220ms;
--frame-toast-stack-transition-easing: cubic-bezier(0.16, 1, 0.3, 1);