Back to components

Modal

zyra-modal

Accessible dialog overlay with focus trap, ESC to close, backdrop dismiss, and flexible header/footer slots.

Component preview

Explore the available states and the real library behavior for this component.

zyra-modal Playground

Control every input live and see the result instantly

Controls
size
title
boolean inputs
Preview
Generated Code
<zyra-modal
  [(open)]="isOpen"
  title="Confirm action"
>
  <p>Modal body content goes here.</p>
  <div slot="footer" class="zyr-modal__footer">
    <zyra-button variant="ghost" (clicked)="isOpen.set(false)">Cancel</zyra-button>
    <zyra-button variant="primary" (clicked)="confirm()">Confirm</zyra-button>
  </div>
</zyra-modal>
Real World Examples
Delete Confirmation

Confirm before a destructive action.

Information

Display additional details on demand.

Required Action

Force the user to make a choice.

Copy-paste example

Drop this into your Angular standalone component and it works out of the box.

modal.demo.ts
import { Component, signal } from '@angular/core';
import { ZyraModal, ZyraButton } from 'zyra-ng-ui';

@Component({
  selector: 'app-demo',
  standalone: true,
  imports: [ZyraModal, ZyraButton],
  template: `
    <zyra-button (clicked)="open.set(true)">Open</zyra-button>
    <zyra-modal [(open)]="open" title="Hello">
      <p>Modal content here.</p>
      <div slot="footer" class="zyr-modal__footer">
        <zyra-button variant="ghost" (clicked)="open.set(false)">Cancel</zyra-button>
        <zyra-button variant="primary" (clicked)="open.set(false)">Confirm</zyra-button>
      </div>
    </zyra-modal>
  `,
})
export class DemoComponent {
  open = signal(false);
}

Variants

All the visual modes and states available for this component.

sm

Compact dialog for quick confirmations (400px)

md

Default size for forms and confirmations (560px)

lg

Wider panel for complex content (720px)

xl

Full-featured dialog for rich editing (900px)

API

All inputs and configuration options for zyra-modal.

PropTypeDefaultDescription
openbooleanfalseTwo-way bound visibility state via [(open)]
titlestring-Dialog heading displayed in the header
size'sm' | 'md' | 'lg' | 'xl''md'Maximum width of the dialog panel
closeablebooleantrueShows a close x button in the header

Accessibility

Built to meet WCAG 2.0 AA. These notes cover the key ARIA, keyboard, and interaction behaviours.

  • Renders with role="dialog" and aria-modal="true" to isolate screen-reader focus
  • Focus is trapped inside the modal while it is open
  • ESC key closes the modal; focus returns to the trigger element on close
  • aria-labelledby links the title to the dialog for screen reader announcement