Skip to main content

Overview

The Modal component displays content in a dialog overlay that appears above the main application content. Modals are useful for focusing user attention on critical information, forms, or actions without navigating away from the current page.

Basic usage

Import the Modal component and control its visibility with the open property:
import { ModalComponent } from '@flowx/angular-ui-toolkit';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [ModalComponent],
  template: `
    <button (click)="openModal()">Open Modal</button>
    
    <flx-modal
      [open]="isOpen"
      [title]="'Confirmation'"
      (close)="closeModal()">
      <p>Are you sure you want to proceed?</p>
      <div slot="footer">
        <button (click)="closeModal()">Cancel</button>
        <button (click)="confirm()">Confirm</button>
      </div>
    </flx-modal>
  `
})
export class ExampleComponent {
  isOpen = false;
  
  openModal() {
    this.isOpen = true;
  }
  
  closeModal() {
    this.isOpen = false;
  }
  
  confirm() {
    console.log('Confirmed');
    this.closeModal();
  }
}

Component selector

<flx-modal></flx-modal>

Properties

open
boolean
default:"false"
required
Controls whether the modal is visible. Use two-way binding with [(open)] for automatic state management.
title
string
The title displayed in the modal header.
size
'small' | 'medium' | 'large' | 'fullscreen'
default:"'medium'"
Controls the width of the modal dialog:
  • small: 400px max width
  • medium: 600px max width
  • large: 900px max width
  • fullscreen: Full viewport size
closeOnBackdropClick
boolean
default:"true"
When true, clicking the backdrop (overlay) closes the modal.
closeOnEscape
boolean
default:"true"
When true, pressing the Escape key closes the modal.
showCloseButton
boolean
default:"true"
When true, displays a close button (×) in the modal header.
backdropDismiss
boolean
default:"true"
Alias for closeOnBackdropClick. Controls backdrop click behavior.
persistent
boolean
default:"false"
When true, prevents the modal from being closed by backdrop clicks or Escape key. User must use explicit close actions.
scrollable
boolean
default:"true"
When true, allows the modal body to scroll when content exceeds the viewport height.
centered
boolean
default:"true"
When true, vertically centers the modal in the viewport.

Events

close
EventEmitter<void>
Emitted when the modal is closed by any method (backdrop click, Escape key, or close button).
openChange
EventEmitter<boolean>
Emitted when the modal’s open state changes. Useful for two-way binding.
opened
EventEmitter<void>
Emitted after the modal has fully opened (animation complete).
closed
EventEmitter<void>
Emitted after the modal has fully closed (animation complete).

Content projection

The Modal component supports multiple content areas:

Default content slot

<flx-modal [open]="isOpen" [title]="'Simple Modal'">
  <!-- Main modal content -->
  <p>This content appears in the modal body</p>
</flx-modal>

Named slots

<flx-modal [open]="isOpen">
  <div slot="header">
    <h2>Custom Header</h2>
    <span class="badge">New</span>
  </div>
  <p>Modal content</p>
</flx-modal>

Examples

Use a modal for confirmation dialogs:
@Component({
  template: `
    <button (click)="showDeleteConfirmation()">Delete Item</button>
    
    <flx-modal
      [(open)]="showConfirmation"
      [title]="'Confirm Deletion'"
      [size]="'small'"
      [persistent]="true">
      <div class="confirmation-content">
        <p>Are you sure you want to delete this item?</p>
        <p class="warning">This action cannot be undone.</p>
      </div>
      <div slot="footer">
        <button
          class="btn-secondary"
          (click)="showConfirmation = false">
          Cancel
        </button>
        <button
          class="btn-danger"
          (click)="deleteItem()">
          Delete
        </button>
      </div>
    </flx-modal>
  `,
  styles: [`
    .confirmation-content {
      padding: 1rem 0;
    }
    .warning {
      color: var(--warning-color);
      font-weight: 500;
    }
  `]
})
export class DeleteConfirmationComponent {
  showConfirmation = false;
  
  showDeleteConfirmation() {
    this.showConfirmation = true;
  }
  
  deleteItem() {
    console.log('Item deleted');
    this.showConfirmation = false;
  }
}
When using persistent modals, always provide a clear way for users to close or cancel the modal, such as a “Cancel” button in the footer.

Accessibility

The Modal component follows accessibility best practices:
  • Traps focus within the modal when open
  • Returns focus to the trigger element when closed
  • Uses proper ARIA attributes (role="dialog", aria-modal="true")
  • Supports keyboard navigation (Tab, Shift+Tab, Escape)
  • Announces modal opening to screen readers
  • Prevents background scrolling when open
Avoid nesting modals within other modals, as this creates a confusing user experience and accessibility issues. Consider using a multi-step modal or drawer component instead.

Styling

Customize modal appearance using CSS custom properties:
flx-modal {
  --modal-backdrop-color: rgba(0, 0, 0, 0.5);
  --modal-background: #ffffff;
  --modal-border-radius: 8px;
  --modal-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  --modal-header-padding: 20px;
  --modal-body-padding: 20px;
  --modal-footer-padding: 16px 20px;
  --modal-max-height: 90vh;
}

Common use cases

  • Confirmation dialogs: Confirm destructive actions
  • Forms: Collect user input without page navigation
  • Alerts and notifications: Display important messages
  • Image galleries: Show full-size images or media
  • Detail views: Display detailed information about an item
  • Wizards: Guide users through multi-step processes
  • Document preview: Show documents, PDFs, or other content

Build docs developers (and LLMs) love