Skip to main content
The Message component displays informational content with visual styling that indicates importance, context, or status.

Usage

Use the flx-message component to communicate important information to users.
<flx-message>This is a default message</flx-message>

Selector

flx-message

Properties

state
'default' | 'info' | 'success' | 'warning' | 'error'
default:"'default'"
Semantic state that determines the message’s color scheme and default icon.
  • default: Neutral message
  • info: Informational content
  • success: Successful operations
  • warning: Warnings or cautions
  • error: Errors or critical issues
appearance
'fill' | 'border' | 'text'
default:"'border'"
Visual style variant of the message.
  • fill: Filled background with colored background
  • border: White background with colored border
  • text: Minimal styling with colored text
icon
string
Name of the icon to display. If not provided, a default icon based on the state is used.
showIcon
boolean
default:"true"
Whether to display an icon in the message.
dismissible
boolean
default:"false"
When true, shows a close button allowing users to dismiss the message.
title
string
Optional title displayed above the message content.

Events

dismissed
EventEmitter<void>
Emitted when the user clicks the dismiss button (only applicable when dismissible is true).

Message states

Default

<flx-message>
  This is a default informational message.
</flx-message>

Info

<flx-message state="info">
  Did you know? You can customize your dashboard layout.
</flx-message>

Success

<flx-message state="success">
  Your profile has been updated successfully.
</flx-message>

Warning

<flx-message state="warning">
  Your storage is almost full. Consider upgrading your plan.
</flx-message>

Error

<flx-message state="error">
  Unable to connect to the server. Please try again later.
</flx-message>

Appearance variants

Fill

Filled messages with colored backgrounds, ideal for high-visibility notifications.
<flx-message appearance="fill" state="info">
  This is a filled info message.
</flx-message>

<flx-message appearance="fill" state="success">
  This is a filled success message.
</flx-message>

<flx-message appearance="fill" state="warning">
  This is a filled warning message.
</flx-message>

<flx-message appearance="fill" state="error">
  This is a filled error message.
</flx-message>

Border

Messages with colored borders and white backgrounds, suitable for most contexts.
<flx-message appearance="border" state="info">
  This is a bordered info message.
</flx-message>

<flx-message appearance="border" state="success">
  This is a bordered success message.
</flx-message>

Text

Minimal messages with colored text only, for subtle notifications.
<flx-message appearance="text" state="info">
  This is a text-only info message.
</flx-message>

<flx-message appearance="text" state="warning">
  This is a text-only warning message.
</flx-message>

With titles

<flx-message state="success" title="Success!">
  Your application has been submitted and is now under review.
</flx-message>

<flx-message state="error" title="Validation Error">
  Please correct the following issues before submitting:
  <ul>
    <li>Email address is required</li>
    <li>Password must be at least 8 characters</li>
  </ul>
</flx-message>

Custom icons

<flx-message state="info" icon="lightbulb">
  Pro tip: Use keyboard shortcuts to navigate faster.
</flx-message>

<flx-message state="warning" icon="shield">
  Enable two-factor authentication to secure your account.
</flx-message>

<flx-message state="success" icon="rocket">
  Your deployment is complete and live!
</flx-message>

Dismissible messages

import { Component } from '@angular/core';

@Component({
  selector: 'app-notification',
  template: `
    <flx-message 
      *ngIf="showMessage"
      state="info" 
      [dismissible]="true"
      (dismissed)="onDismiss()">
      This message can be dismissed.
    </flx-message>
  `
})
export class NotificationComponent {
  showMessage = true;
  
  onDismiss(): void {
    this.showMessage = false;
  }
}
<flx-message state="info">
  Your trial period ends in 3 days. 
  <a href="/upgrade">Upgrade now</a> to continue using premium features.
</flx-message>

<flx-message state="warning">
  Some features are unavailable. 
  <a href="/status">Check system status</a> for more information.
</flx-message>

Form validation messages

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-form-with-messages',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div class="form-group">
        <label>Email</label>
        <input type="email" formControlName="email" />
        
        <flx-message 
          *ngIf="form.get('email')?.invalid && form.get('email')?.touched"
          state="error"
          appearance="text"
          [showIcon]="false">
          Please enter a valid email address.
        </flx-message>
      </div>
      
      <div class="form-group">
        <label>Password</label>
        <input type="password" formControlName="password" />
        
        <flx-message 
          *ngIf="form.get('password')?.invalid && form.get('password')?.touched"
          state="error"
          appearance="text"
          [showIcon]="false">
          Password must be at least 8 characters long.
        </flx-message>
      </div>
      
      <flx-message 
        *ngIf="submitError"
        state="error"
        [dismissible]="true"
        (dismissed)="submitError = null">
        {{ submitError }}
      </flx-message>
      
      <button flxButton type="submit" [disabled]="form.invalid">
        Submit
      </button>
    </form>
  `
})
export class FormWithMessagesComponent {
  form: FormGroup;
  submitError: string | null = null;
  
  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      email: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(8)]]
    });
  }
  
  onSubmit(): void {
    if (this.form.valid) {
      // Handle form submission
      console.log(this.form.value);
    }
  }
}

Notification system

import { Component, OnInit } from '@angular/core';
import { interval, Subject, takeUntil } from 'rxjs';

interface Notification {
  id: number;
  message: string;
  state: 'info' | 'success' | 'warning' | 'error';
  timeout?: number;
}

@Component({
  selector: 'app-notification-center',
  template: `
    <div class="notification-container">
      <flx-message 
        *ngFor="let notification of notifications"
        [state]="notification.state"
        [dismissible]="true"
        (dismissed)="dismiss(notification.id)">
        {{ notification.message }}
      </flx-message>
    </div>
  `,
  styles: [`
    .notification-container {
      position: fixed;
      top: 16px;
      right: 16px;
      width: 400px;
      z-index: 1000;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
  `]
})
export class NotificationCenterComponent implements OnInit {
  notifications: Notification[] = [];
  private destroy$ = new Subject<void>();
  private nextId = 1;
  
  ngOnInit(): void {
    // Auto-remove notifications after timeout
    interval(1000)
      .pipe(takeUntil(this.destroy$))
      .subscribe(() => this.cleanupExpiredNotifications());
  }
  
  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }
  
  addNotification(message: string, state: Notification['state'], timeout = 5000): void {
    const notification: Notification = {
      id: this.nextId++,
      message,
      state,
      timeout: Date.now() + timeout
    };
    this.notifications.push(notification);
  }
  
  dismiss(id: number): void {
    this.notifications = this.notifications.filter(n => n.id !== id);
  }
  
  private cleanupExpiredNotifications(): void {
    const now = Date.now();
    this.notifications = this.notifications.filter(
      n => !n.timeout || n.timeout > now
    );
  }
}

Theming

The Message component uses CSS custom properties for theming:
:root {
  --flxTheme-message-borderRadius: 4px;
  --flxTheme-message-borderWidth: 1px;
  --flxTheme-message-fontFamily: inherit;
  --flxTheme-message-fontSize: 14px;
  --flxTheme-message-fontWeight: 400;
  --flxTheme-message-lineHeight: 1.5;
  --flxTheme-message-gap: 12px;
  --flxTheme-message-paddingLeft: 16px;
  --flxTheme-message-paddingRight: 16px;
  --flxTheme-message-shadow: none;
  
  /* State-specific colors */
  --flxTheme-message-color: #333333;
  --flxTheme-message-backgroundColor: #ffffff;
  --flxTheme-message-borderColor: #d0d0d0;
  --flxTheme-message-iconColor: invert(0%);
  --flxTheme-message-linkColor: #3b82f6;
}

Accessibility

  • Messages use appropriate ARIA roles to communicate their purpose to screen readers
  • Color is not the only indicator of state (icons and text provide context)
  • Dismissible messages include accessible close buttons with proper labels
  • Focus management ensures keyboard users can interact with all message elements
Error messages should be announced to screen readers using ARIA live regions for dynamic content.

Best practices

Use message states consistently across your application to build user familiarity with your notification patterns.
  • Keep messages concise and actionable
  • Use success messages to confirm user actions
  • Place error messages near the relevant form fields or actions
  • Avoid showing too many messages simultaneously
  • Provide clear next steps or links to resolve issues
  • Auto-dismiss informational messages, but keep errors visible until dismissed
Don’t rely solely on color to convey message importance. Always include icons and clear text.

Build docs developers (and LLMs) love