@teqbench/tbx-mat-notifications provides transient, unobtrusive feedback for Angular applications. It is a thin, opinionated layer on top of Angular Material's snackbar that fills the gap left by the bare primitive: severity-leveled convenience methods, a FIFO queue so rapid-fire notifications don't overlap, a synchronous ref returned immediately, and consistent visual treatment across severities.
Consumers inject(TbxMatNotificationService) and call success(), error(), warning(), information(), help(), or default() with a message and optional config for the common severity-leveled cases. For full control over every setting — severity, message, duration, countdown visibility, severity-icon visibility, close-button visibility, action button config, and a passthrough to the native MatSnackBarConfig (position, politeness, custom panel classes) — call show() directly with the complete TbxMatNotificationConfig.
Each call returns a TbxMatNotificationRef synchronously so callers can await the dismissal result without losing their place in the queue. Behind the scenes, if another notification is already visible, the new one waits; when the active one dismisses, the next one opens — no overlap, no fighting over the snackbar slot.
Severity (success, error, warning, information, help) drives both the icon and the color scheme via dedicated CSS custom properties, independent of the active M3 theme palette. An optional single action button supports Material's standard button appearances (text, filled, tonal, outlined, elevated) plus an icon-only variant, with defaults that cascade from per-notification to provider-level to built-in. A pure-CSS countdown bar (opt-in via showCountdown) renders progress toward auto-dismissal without requiring any animation framework.
The library is designed for Angular 21+ zoneless applications, uses signal inputs for reactive state (isActive(), pendingCount()), and exposes a pluggable icon resolver so consumers can use Material Symbols font icons or bundled SVG icons without changing component code. The native MatSnackBarRef is exposed via the returned ref's snackBarRef promise for consumers that need the underlying instance.
When to use
Notifications are one of three message surfaces in the TeqBench component family. Choose based on the weight of the message and how much interaction it needs:
@teqbench/tbx-mat-notifications (this package) — small, transient messages with at most one action control (e.g. an Undo, Retry, View, or Dismiss button). Ideally one line of text, two lines acceptable. Use notifications to acknowledge something without interrupting the user's flow.
- `@teqbench/tbx-mat-banners` — wide, persistent messages with multiple action controls (i.e. buttons, checkboxes, toggles, radio groups, toggle groups). Use a banner when the message needs the user's attention and may offer a few follow-up choices.
- `@teqbench/tbx-mat-dialogs` — heavier, focused interactions for arbitrary content. Use a dialog when the message is long, the choices are many, or the interaction is complex.
If a notification grows beyond one short line or needs more than one action, that's a signal to escalate to a banner.
At a glance
- Severity-leveled API — Convenience methods for success, error, warning, information, and help with matching icons and colors.
- Material snackbar base — Thin opinionated layer over Angular Material's MatSnackBar with consistent visual treatment.
- FIFO queue — One notification at a time, with signal-based isActive and pendingCount state.
- Synchronous ref — Service methods return TbxMatNotificationRef immediately, with promises for the native ref and dismiss result.
- Optional action button — Single action with text, filled, tonal, outlined, elevated, or icon-only appearance and cascading defaults.
- Dismiss reason tracking — Result promise resolves with Action, Close, Timeout, or one of two programmatic dismiss reasons.
- Pure-CSS countdown bar — Opt-in visual progress toward auto-dismissal, no animation framework required.
- Configurable duration — Default 10s; positive values used as-is; zero or negative means indefinite.
- Theming via CSS custom properties — Per-severity colors, opacity tokens for button variants, and layout gaps exposed as CSS variables.
- Pluggable icons — Font (Material Symbols) or SVG icon resolver services via DI token, with optional per-action overrides.
- Native ref exposure — Underlying MatSnackBarRef available via the returned ref's snackBarRef promise for advanced use.
- Zoneless ready — Built for Angular 21+ zoneless applications using signal-based reactive state.
Concepts
- Severity level — A classification (success, error, warning, information, help) that selects the icon and color scheme applied to a notification.
- Action button — An optional single button rendered inside the notification; its click resolves the dismiss result with reason Action.
- Dismiss reason — The cause of a notification closing — action button, close button, timeout, or one of two programmatic paths (single or all).
- Queue — A FIFO list of pending notifications. One is visible at a time; queued notifications render in order as each resolves.
- Countdown bar — A pure-CSS progress bar rendered along the notification's edge that depletes over the configured duration. Opt-in via showCountdown.
- Provider config — The DI-provided configuration (TBX_MAT_NOTIFICATION_PROVIDER_CONFIG) that supplies the severity icon resolver, optional close icon resolver, and application-wide action defaults.
- Action appearance cascade — Per-notification action.actionButtonType overrides the provider's actionConfig.buttonType, which in turn overrides the built-in default of 'text'.
- Icon resolver service — A pluggable service that maps a severity level or a named icon to either a Material Symbols ligature (font) or an SVG markup string.
Services
TbxMatNotificationCloseFontIconService
Default font-based close button icon service
Extends TbxMatFontIconService from @teqbench/tbx-mat-icons and registers the 'close' Material Symbols ligature. Used as the package-provided default for TbxMatNotificationProviderConfig.closeIconResolverService when the consumer does not supply a custom close icon resolver.
No default SVG close icon service is provided. Consumers who want SVG close icons must create a concrete subclass of TbxMatSvgIconService from @teqbench/tbx-mat-icons and provide it via TbxMatNotificationProviderConfig.closeIconResolverService.
fontSet resolution
The fontSet is resolved by TbxMatFontIconService's fallback chain:
- Explicit constructor argument —
new TbxMatNotificationCloseFontIconService('material-symbols-sharp')
TBX_MAT_FONT_ICON_DEFAULT_FONT_SET token — set once in app.config.ts
MAT_ICON_DEFAULT_OPTIONS.fontSet — Angular Material's global icon default
- Error — if none of the above provides a fontSet
Example
Using with MAT_ICON_DEFAULT_OPTIONS:
import { MAT_ICON_DEFAULT_OPTIONS } from '@angular/material/icon';
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG, TbxMatNotificationSeverityFontIconService }
from '@teqbench/tbx-mat-notifications';
providers: [
{ provide: MAT_ICON_DEFAULT_OPTIONS, useValue: { fontSet: 'material-symbols-rounded' } },
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeverityFontIconService(),
}),
},
]
Example
Providing a custom close icon:
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG, TbxMatNotificationSeverityFontIconService,
TbxMatNotificationCloseFontIconService } from '@teqbench/tbx-mat-notifications';
class MyCloseIconService extends TbxMatNotificationCloseFontIconService {
protected override initialize(): void {
this.register('close', 'cancel');
}
}
providers: [
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeverityFontIconService('material-symbols-rounded'),
closeIconResolverService: new MyCloseIconService('material-symbols-rounded'),
}),
},
]
TbxMatNotificationService
Application-wide notification service
Wraps Angular Material's MatSnackBar with typed severity levels, configurable duration, and a custom snackbar component that displays an optional severity icon + message + optional action button + optional dismiss button.
Notifications are queued FIFO and displayed one at a time. When the current notification is dismissed (manually or by timeout), the next queued notification is shown automatically. This follows Material Design guidelines — only one snackbar should be visible at a time.
All public methods return a TbxMatNotificationRef synchronously, containing the consumer's config and two promises: - snackBarRef — resolves with the native MatSnackBarRef when the notification displays, or null if cleared from the queue. - result — resolves with a TbxMatNotificationResult containing the TbxMatNotificationDismissReason when the notification is dismissed.
Consumers who do not need the ref or result should use the void prefix to suppress unhandled-promise lint warnings:
void this.notificationService.success('Saved');
Queue state is exposed via Angular signals for reactive consumption: - isActive() — whether a notification is currently visible - pendingCount() — number of notifications waiting in the queue
When to use
Inject the service and call the convenience methods for each severity level. Use show() when full control over configuration is needed. Use dismiss() and dismissAll() to programmatically clear notifications. Bind isActive() and pendingCount() in templates or computed signals for reactive state.
Example
Fire-and-forget convenience methods:
private readonly notify = inject(TbxMatNotificationService);
void this.notify.success('Item saved successfully.');
void this.notify.error('Failed to load data. Please try again.');
Example
Reacting to action dismissal:
const ref = this.notify.success('Item deleted.', {
action: { label: 'Undo' },
duration: 30_000,
});
const result = await ref.result;
if (result.dismissReason === TbxMatNotificationDismissReason.Action) {
this.undoDelete();
}
Example
Accessing the native snackbar ref:
const ref = this.notify.error('Upload failed.', {
action: { label: 'Retry' },
});
const snackBarRef = await ref.snackBarRef;
snackBarRef?.afterOpened().subscribe(() => {
console.log('Notification is visible');
});
TbxMatNotificationSeverityFontIconService
Default font-based severity notification icon service
Extends TbxMatSeverityFontIconService from @teqbench/tbx-mat-severity-theme and registers the shared default Material Symbols ligatures (TBX_MAT_SEVERITY_DEFAULT_FONT_LIGATURES) for every severity level. The inherited resolve() and severity methods (default(), success(), error(), etc.) work via the registered mappings.
fontSet resolution
The fontSet is resolved by TbxMatFontIconService's fallback chain:
- Explicit constructor argument —
new TbxMatNotificationSeverityFontIconService('material-symbols-sharp')
TBX_MAT_FONT_ICON_DEFAULT_FONT_SET token — set once in app.config.ts
MAT_ICON_DEFAULT_OPTIONS.fontSet — Angular Material's global icon default
- Error — if none of the above provides a fontSet
For steps 1 and 2, the consuming component must bind [fontSet] on <mat-icon>. For step 3, <mat-icon> already uses the global default — no binding needed.
Example
Using with MAT_ICON_DEFAULT_OPTIONS (no explicit fontSet needed):
import { MAT_ICON_DEFAULT_OPTIONS } from '@angular/material/icon';
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG, TbxMatNotificationSeverityFontIconService }
from '@teqbench/tbx-mat-notifications';
providers: [
{ provide: MAT_ICON_DEFAULT_OPTIONS, useValue: { fontSet: 'material-symbols-rounded' } },
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeverityFontIconService(),
}),
},
]
Example
Using with an explicit fontSet:
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG, TbxMatNotificationSeverityFontIconService }
from '@teqbench/tbx-mat-notifications';
providers: [
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeverityFontIconService('material-symbols-rounded'),
}),
},
]
Example
Using with TBX_MAT_FONT_ICON_DEFAULT_FONT_SET token:
import { TBX_MAT_FONT_ICON_DEFAULT_FONT_SET, TBX_MAT_ICON_FONT_SET_MATERIAL_SYMBOLS_ROUNDED }
from '@teqbench/tbx-mat-icons';
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG, TbxMatNotificationSeverityFontIconService }
from '@teqbench/tbx-mat-notifications';
providers: [
{ provide: TBX_MAT_FONT_ICON_DEFAULT_FONT_SET, useValue: TBX_MAT_ICON_FONT_SET_MATERIAL_SYMBOLS_ROUNDED },
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeverityFontIconService(),
}),
},
]
TbxMatNotificationSeveritySvgIconService
Default SVG-based severity notification icon service
Extends TbxMatSeveritySvgIconService from @teqbench/tbx-mat-severity-theme and registers the shared default SVG icons (TBX_MAT_SEVERITY_DEFAULT_SVG_ICONS) for every severity level. The inherited resolve() and severity methods (default(), success(), error(), etc.) work via the registered mappings.
Default icons ship with @teqbench/tbx-mat-severity-theme. Subclasses can override any default by overriding initialize() and calling register() with the same key and different SVG markup.
Example
Using the defaults directly:
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG, TbxMatNotificationSeveritySvgIconService }
from '@teqbench/tbx-mat-notifications';
providers: [
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeveritySvgIconService(),
}),
},
]
Example
Subclassing with custom SVG markup:
import { Injectable } from '@angular/core';
import { TbxMatNotificationSeveritySvgIconService } from '@teqbench/tbx-mat-notifications';
import { TbxMatSeverityLevel } from '@teqbench/tbx-mat-severity-theme';
@Injectable()
export class MyNotificationSvgIcons extends TbxMatNotificationSeveritySvgIconService {
protected override initialize(): void {
super.initialize();
this.register(TbxMatSeverityLevel.Success, '<svg>...</svg>');
}
}
Components
TbxMatNotificationComponent
Custom snackbar content component for typed notifications
Rendered inside MatSnackBar via openFromComponent(). Receives its data through MAT_SNACK_BAR_DATA injection token as an internal DTO.
Template element order
severity icon→message→action button→close button
All elements are optional except the message. The action button and close button both render within matSnackBarActions and use the matSnackBarAction directive.
Action button rendering
When data.actionLabel is set, the component renders an action button. The button appearance is determined by data.actionButtonType: - 'text' / 'filled' / 'elevated' / 'outlined' / 'tonal' — renders mat-button with [matButton] input binding and optional icon. - 'icon' — renders mat-icon-button with aria-label from data.actionLabel.
Icon rendering
Icons are resolved to a ResolvedIcon ({ name, isSvg }) via computed signals and a shared resolveIcon() helper. Three icon categories exist: severity, action, and close — each backed by a resolver service that determines whether to render a font ligature or an SVG icon.
A shared ng-template (#tbxNgIconTemplate) handles the font vs SVG branching for all icon sites. Each call site passes a ResolvedIcon via ngTemplateOutlet context. The template guards against null internally, so call sites do not need their own null checks.
Content projection and ngProjectAs
Angular Material's button component uses ng-content select to project mat-icon elements into leading and trailing slots: - mat-icon:not([iconPositionEnd]) — leading slot (before the label) - mat-icon[iconPositionEnd] — trailing slot (after the label)
When mat-icon is rendered via ngTemplateOutlet inside an ng-container, Angular's projection matching sees ng-container — not mat-icon — as the direct child of the button. The icon falls into the default <ng-content> slot (.mdc-button__label) instead of the icon slot, breaking alignment.
The ngProjectAs attribute on ng-container solves this. It tells Angular's projection matching (isSelectorInSelectorList in the runtime) to treat the ng-container as if it were the specified selector. The match is exact — the parsed ngProjectAs value must match the parsed ng-content select value element-by-element: - ngProjectAs="mat-icon:not([iconPositionEnd])" — matches the leading slot selector exactly - ngProjectAs="mat-icon[iconPositionEnd]" — matches the trailing slot selector exactly
A plain ngProjectAs="mat-icon" does NOT match the leading slot because the slot selector is mat-icon:not([iconPositionEnd]) — the parsed arrays have different lengths and isSelectorInSelectorList requires exact element-by-element equality.
Countdown bar
Renders only when data.showCountdown is true AND data.duration is positive (not indefinite). Setting showCountdown: true with duration <= 0 has no visible effect — an indefinite notification has no countdown to display.
Example
Rendered internally by TbxMatNotificationService:
void this.notificationService.success('Item saved.');
Interfaces
TbxMatNotificationAction
Configuration for a notification action button
Defines the content and appearance of the optional action button rendered in the notification snackbar. The action button sits between the message and the close button in the M3 snackbar anatomy.
Resolution Cascade
Properties set here override the corresponding property on TbxMatNotificationProviderActionConfig. When neither is set, the following defaults apply:
actionButtonType — 'text' - iconPosition — TbxMatNotificationIconPosition.Before - actionIconResolverService — none (required when iconName is set and the resolved button type uses icons)
Fallback Rules
The service applies fallback rules when the provided combination of fields is invalid:
actionButtonType is 'icon' but iconName is not set — falls back to 'text' and renders the label as a text button. - actionButtonType is 'text' and iconName is set — the icon is ignored; only the label is rendered. - iconName is set and the resolved button type requires an icon, but no actionIconResolverService is available (neither per-notification nor provider-level) — logs an error and does not render the action.
When to use
Add an action to a notification to let users respond inline (e.g., undo, retry, view). Set on TbxMatNotificationConfig.action or passed via the convenience method config args.
Example
Text action button:
this.notificationService.success('Item deleted', {
action: { label: 'Undo' },
duration: 30_000,
});
Example
Icon-only action button:
this.notificationService.error('Upload failed', {
action: {
label: 'Retry',
iconName: 'refresh',
actionButtonType: 'icon',
actionIconResolverService: myIconService,
},
});
Example
Tonal button with icon:
this.notificationService.warning('Connection lost', {
action: {
label: 'Retry',
iconName: 'sync',
actionButtonType: 'tonal',
iconPosition: TbxMatNotificationIconPosition.Before,
actionIconResolverService: myIconService,
},
});
TbxMatNotificationProviderActionConfig
Provider-level defaults for notification action buttons
Set on TbxMatNotificationProviderConfig.actionConfig to establish application-wide defaults for action button appearance, icon position, and icon resolution. Individual notifications can override any of these via TbxMatNotificationAction.
All properties are optional. When a property is not set here and not overridden per-notification, the following defaults apply:
actionButtonType — 'text' - iconPosition — TbxMatNotificationIconPosition.Before - actionIconResolverService — none
When to use
Configure action button defaults in the provider config when all or most action buttons in the application share the same appearance or icon resolver. Omit entirely if action buttons are not used or defaults are sufficient.
Example
Provider config with tonal action defaults:
import { TBX_MAT_NOTIFICATION_PROVIDER_CONFIG }
from '@teqbench/tbx-mat-notifications';
providers: [
{
provide: TBX_MAT_NOTIFICATION_PROVIDER_CONFIG,
useFactory: () => ({
severityIconResolverService: new TbxMatNotificationSeverityFontIconService('material-symbols-rounded'),
actionConfig: {
actionButtonType: 'tonal',
iconPosition: TbxMatNotificationIconPosition.Before,
actionIconResolverService: new MyActionIconService(),
},
}),
},
]
TbxMatNotificationRef
Reference to a queued or active notification
Returned synchronously from all TbxMatNotificationService methods (show(), success(), error(), warning(), information(), help()). Contains three members:
config — the consumer-provided configuration, available immediately. - snackBarRef — a promise that resolves with the native MatSnackBarRef when the notification is displayed (comes off the FIFO queue), or null if the notification was cleared from the queue before being displayed (e.g., via TbxMatNotificationService.dismissAll). - result — a promise that resolves with a TbxMatNotificationResult containing the TbxMatNotificationDismissReason when the notification is dismissed.
Native Ref vs Service Dismiss Methods
The snackBarRef promise exposes the full MatSnackBarRef API, including dismiss(), dismissWithAction(), afterOpened(), afterDismissed(), and onAction(). Using the native ref for read-only operations (subscriptions, inspection) is safe and recommended. However, calling dismiss() or dismissWithAction() directly on the native ref bypasses the enriched TbxMatNotificationDismissReason tracking — the result promise may resolve with an incorrect reason (e.g., Timeout instead of ProgrammaticDismissCurrent).
For accurate dismiss reason tracking, use the service convenience methods (TbxMatNotificationService.dismiss, TbxMatNotificationService.dismissAll) or the component's action/close buttons.
Fire-and-Forget Usage
Consumers who do not need the dismiss result or native ref should prefix the call with void to suppress unhandled-promise lint warnings:
void this.notificationService.success('Saved');
When to use
Capture the returned ref to react to notification dismissal, access the native snackbar ref for subscriptions, or inspect the original config.
Example
Reacting to action dismissal:
const ref = this.notificationService.success('Item deleted', {
action: { label: 'Undo' },
duration: 30_000,
});
const result = await ref.result;
if (result.dismissReason === TbxMatNotificationDismissReason.Action) {
this.undoDelete();
}
Example
Subscribing to native ref events:
const ref = this.notificationService.error('Upload failed', {
action: { label: 'Retry' },
});
const snackBarRef = await ref.snackBarRef;
snackBarRef?.afterOpened().subscribe(() => {
console.log('Notification is visible');
});
Example
Fire-and-forget:
void this.notificationService.success('Saved');
TbxMatNotificationResult
Result returned when a notification is dismissed
Resolved by the TbxMatNotificationRef.result promise when a notification is dismissed for any reason — user action, timeout, or programmatic dismissal. The dismissReason property indicates which trigger caused the dismissal.
When to use
Await the result promise from any TbxMatNotificationService method to determine how a notification was dismissed and react accordingly.
Example
const ref = this.notificationService.success('Item deleted', {
action: { label: 'Undo' },
duration: 30_000,
});
const result: TbxMatNotificationResult = await ref.result;
if (result.dismissReason === TbxMatNotificationDismissReason.Action) {
this.undoDelete();
}
Enums
TbxMatNotificationDismissReason
Reason a notification was dismissed
Returned as part of TbxMatNotificationResult via TbxMatNotificationRef.result. Each value corresponds to a distinct dismissal trigger:
Action — the user clicked the action button. - Close — the user clicked the close button. - Timeout — the notification auto-dismissed after the configured duration expired. - ProgrammaticDismissAll — TbxMatNotificationService.dismissAll was called, clearing the queue and dismissing the active notification. - ProgrammaticDismissCurrent — TbxMatNotificationService.dismiss was called, dismissing only the currently active notification.
When the consumer dismisses via the native MatSnackBarRef obtained from TbxMatNotificationRef.snackBarRef, the enriched reason tracking is bypassed — the result may resolve with Timeout instead of the expected programmatic reason. Use the service convenience methods for accurate reason tracking.
When to use
Inspect the dismiss reason after awaiting the result promise to determine which user or programmatic action closed the notification.
Example
const ref = this.notificationService.success('Item deleted', {
action: { label: 'Undo' },
duration: 30_000,
});
const result = await ref.result;
if (result.dismissReason === TbxMatNotificationDismissReason.Action) {
this.undoDelete();
}
TbxMatNotificationIconPosition
Position of an icon relative to the action button label
Controls whether an icon renders before or after the label text on an action button. Applies only when the resolved TbxMatNotificationActionButtonAppearance is not 'icon' (icon-only buttons have no label to position relative to).
The position can be set at the provider level via TbxMatNotificationProviderActionConfig.iconPosition or per-notification via TbxMatNotificationAction.iconPosition. Per-notification takes precedence. When neither is set, defaults to Before.
When to use
Set the icon position when an action button has both a label and an icon, and the default leading position is not desired.
Example
this.notificationService.success('File uploaded', {
action: {
label: 'View',
iconName: 'open_in_new',
iconPosition: TbxMatNotificationIconPosition.After,
},
});
Types
TbxMatNotificationActionButtonAppearance
Visual appearance of a notification action button
Union of MatButtonAppearance ('text' | 'filled' | 'elevated' | 'outlined' | 'tonal') and the custom 'icon' value for icon-only action buttons.
Values other than 'icon' map directly to the [appearance] input on Angular Material button directives. The 'icon' value renders a mat-icon-button instead.
This type is coupled to MatButtonAppearance from @angular/material/button. If Angular Material renames, removes, or adds values to that type, this type will need a corresponding update.
The appearance can be set at the provider level via TbxMatNotificationProviderActionConfig.actionButtonType or per-notification via TbxMatNotificationAction.actionButtonType. Per-notification takes precedence. When neither is set, defaults to 'text' per M3 guidelines (snackbars are the lowest-priority notification surface).
When to use
Specify the action button appearance when the default 'text' style is not desired.
Example
this.notificationService.warning('Connection lost', {
action: {
label: 'Retry',
actionButtonType: 'tonal',
},
});
this.notificationService.error('Upload failed', {
action: {
label: 'Retry',
iconName: 'refresh',
actionButtonType: 'icon',
},
});
Accessibility
- Snackbar container. Notifications render inside Angular Material's snackbar overlay, which announces new snackbars to assistive technology via its built-in politeness handling. Consumers can pass
politeness through the snackBarConfig passthrough on TbxMatNotificationConfig to customize the announcement level ('polite', 'assertive', or 'off').
- Keyboard. The action button and close button are focusable in DOM order.
Enter and Space activate them; the native Material button keyboard behavior is preserved.
- Focus. Focus is not moved into the notification — they are non-blocking surfaces and should not steal focus from the user's current task.
- Action button labeling. Icon-only action buttons (
actionButtonType: 'icon') use the label field as the button's aria-label, so screen readers announce the action's purpose even when no visible text is rendered.
- Close button labeling. The close button has a fixed
aria-label="Dismiss notification" so its purpose is announced consistently across severities and configurations.
- Severity icons. Severity icons are decorative and marked
aria-hidden; the severity meaning is carried by the message text itself, not by the icon alone.
- Color contrast. The default severity palette meets WCAG AA contrast for body text on each background. Overriding the severity CSS custom properties is the consumer's responsibility to re-verify.