A toast is a non-modal message displayed on top of all elements on the screen. It differs from a popup in that it appears in the top right corner of the screen and is not tied to any specific interface element. It is used when no mandatory user response is required (i.e., a modal window is not needed).
The recommended message length is 144 characters, and the title length is 80 characters. Long text is not truncated — the toast grows in height.
Information. Any system message that does not require an immediate response, or for which there was no suitable place to embed in the on-screen content. For example, it can inform the user that a background operation has been launched by their command.
Success. A message about a completed operation. May include a "Cancel" button. It is useful to offer the user the option to view the result of the operation, if possible.
Warning. Helps the user avoid an error. This type of toast is used rarely.
Error. Reports an unsuccessful operation when the situation does not require immediate user intervention and work can continue.
Toasts appear in the top right corner. Multiple messages form a stack on the screen. New messages appear at the bottom of the list. If there are many toasts, new ones may extend beyond the bottom boundary of the visible area. Most often, a toast opens in response to a user command, but the system can also show notifications on its own.
By default, toasts are hidden automatically. A message must remain in the toast list for at least 5 seconds before being hidden. Toasts disappear with a 2-second interval after the last dismissal (automatic or manual), so the user has time to read the text and the disappearance does not feel sudden.
The toast is hidden automatically. The message must be shown for at least 5 seconds.
Messages do not disappear over time. The user can hide a toast using the "Close" button.
At the designer's request, a toast may close via a button in the action panel, by following a link in the message text, or after any other event. For example, after a file upload or another process that the toast was reporting on is complete.
When the mouse hovers over or focus is on a message, all toasts stop disappearing. After the mouse leaves or focus is lost, messages with auto-hide begin disappearing one after another with an interval of 2–5 seconds. The condition must be met that the message was shown for at least 5 seconds and 2 seconds have passed between toast closings.
The option to hide a toast using the icon button in the corner is available by default. This action is not duplicated by an element in the action panel.
Sometimes it is useful to make a toast without a close × icon button. For example, when you need to show the progress of a background operation. In this case, a "Cancel" button with text should be placed in the action panel to allow interrupting the operation.
Do not use toasts to confirm commands.
The toast action panel can contain two elements. As a rule, triggering an action closes the toast.
If there are more actions, the primary one should be shown first, and the rest hidden in a "More" menu. The menu name may differ if another name is more appropriate.
A toast notification may contain a button to cancel an operation. The close × icon button cannot serve this purpose — it only hides the toast.
A link can be inserted into the message text (recommendation: no more than one).
Push messages from the Notification Center should be shown as toasts in a unified list with system messages.
At the designer's request, some toast messages may be recorded in the Notification Center. When a toast closes, it is useful to be able to review what happened and read error details. At the same time, there is no requirement to log every Notification Center message.
Key |
Action |
|---|---|
| Tab Shift+Tab | Move to the next or previous focusable element |
| Esc | Close the toast |
The toast appears in the top right corner of the screen. Multiple messages form a stack on the screen; new toasts are added at the bottom of the stack.
The position can be changed using kbqToastConfigurationProvider:
import { kbqToastConfigurationProvider, KbqToastPosition } from '@koobiq/components/toast';
@NgModule({
providers: [
kbqToastConfigurationProvider({ position: KbqToastPosition.BOTTOM_RIGHT })
]
})
The width of the toast is fixed; the height depends on the content.
The toast appears from the left horizontally. As it slides in, the new element becomes fully opaque. The height of the toast panel does not change.
The toast slides horizontally to the right beyond the screen edge. The toast window height does not change. As it slides, the element becomes transparent. Messages below it smoothly rise to fill the freed space in the stack.
Toasts are rendered through the CDK overlay, which by default appends its container to document.body. When the application is mounted inside a Shadow DOM — a common setup for Module Federation micro-frontends that isolate their styles — the toast escapes the shadow root into the light DOM. There it loses the styles and theme tokens scoped to the shadow root (Koobiq theme tokens are defined on the .kbq-light / .kbq-dark ancestor), so the toast appears unstyled.
Use kbqShadowDomOverlayProvider to route all CDK overlays (toast, modal, dropdown, tooltip, etc.) into the shadow root:
import { bootstrapApplication } from '@angular/platform-browser';
import { kbqShadowDomOverlayProvider } from '@koobiq/components/core';
bootstrapApplication(AppComponent, {
providers: [
// Pass the micro-frontend root element (or any element inside its shadow tree).
...kbqShadowDomOverlayProvider(() => document.querySelector('my-mfe-root')!)
]
});
When called without arguments, the application root component element is used to resolve the shadow root. If the host is not inside an open shadow root, the container stays on document.body, so the provider is safe to add unconditionally.
The provider replaces the global
OverlayContainer, so it cannot be combined with another customOverlayContainer(such as CDK'sFullscreenOverlayContainer) — the last provider wins.Besides relocating the container, the provider automatically delivers the CDK structural overlay styles (position,
z-index, backdrop) into the shadow root. The micro-frontend is still responsible for delivering the Koobiq component/theme styles (the.kbq-light/.kbq-darktokens and component CSS) into its shadow root, because globaldocument.headstylesheets do not cross a shadow boundary.
By default each micro-frontend that adds kbqShadowDomOverlayProvider gets its own OverlayContainer, so its overlays render inside its own shadow root and theme. That is the right default when every micro-frontend should keep its own theme.
If instead you want all micro-frontends to share a single overlay container — one stacking context, so overlays opened in different micro-frontends stack by open order — let the host create the container and pass that one instance to every remote:
import { OverlayContainer } from '@angular/cdk/overlay';
import { createApplication } from '@angular/platform-browser';
import { kbqShadowDomOverlayProvider } from '@koobiq/components/core';
// Host: create the single shared container in the host's shadow root.
const hostApp = await createApplication({
providers: [...kbqShadowDomOverlayProvider(() => hostElement)]
});
const sharedOverlayContainer = hostApp.injector.get(OverlayContainer);
// Each remote micro-frontend reuses that same instance instead of creating its own.
const remoteApp = await createApplication({
providers: [{ provide: OverlayContainer, useValue: sharedOverlayContainer }]
});
Trade-offs:
ngOnDestroy removes it.KbqToastService (each service keeps its own stack), so route toasts through one shared service.