Free
Pro

Dialogs

Base UI (Angular) dialogs are modals you open with DialogService.open(), not a router outlet. The CLI copies the overlay, focus trap, and header/body/footer pieces into your app. On the server, open() is a no-op so prerender stays SSR-safe. Close with a typed result via DialogContext.

When to use

  • Confirmations, short forms, and focused tasks that should block the page.
  • When you need a typed close payload from DialogService.open().subscribe().

When not to use

  • Full-page flows — use a route, a drawer, or the cookbooks dialog-form pattern only for modal work.
  • Toasts or status messages — use ToastService instead of a dialog.

Install with npx base-ui-cli add dialog.

free

Basic Dialog

Basic Dialog example below

HTML

Dialog with Form

Dialog containing form elements and date pickers to gather information.

HTML

Confirm Dialog

A simple confirmation dialog for destructive or important actions.

HTML

Scrolling & Full Height

Dialogs with long content automatically enable scrolling in the body while keeps header and footer fixed. Use the height property to set a fixed height or a large enough value for full-screen feel.

HTML

Loading and disabled

While a mutation is in flight, swap the confirm action for base-progress-button and disable dismiss if rollback is unsafe.

HTML

Keyboard & accessibility

Role
role=dialog with aria-modal. Labelled by the header heading.
Focus
CDK FocusTrap captures Tab. On close, focus returns to the element that opened the dialog.

Shortcuts

  • TabCycle focus inside the dialog (focus trap)
  • ShiftTabCycle backwards inside the dialog
  • EscClose and restore focus to the opener

Site-wide VPAT-style notes live on the accessibility report.

Installation

Run the following command to add this component to your project:

bash

npx base-ui-cli add dialog

API Reference

For AI agents

Copy a prompt with the registry name, CLI install, and import — or add the Base UI MCP server.

bash

npx -y base-ui-mcp

Base UI provides standalone components. Import the exact elements you want to use into your component.

typescript (Example)

// Install: npx base-ui-cli add dialog
// Paths are relative to aliases.components (default: src/app/components)
import { DialogBodyComponent } from './dialog/dialog-body/dialog-body.component';
import { DialogCloseDirective } from './dialog/dialog-close.directive';
import { DialogContainer } from './dialog/dialog-container';
import { DialogService } from './dialog/dialog.service';
import { DialogComponent } from './dialog/dialog/dialog.component';

@Component({
  selector: 'app-your-component',
  imports: [
    DialogBodyComponent,
    DialogCloseDirective,
    DialogComponent
  ],
  template: `...`
})
export class YourComponent {
  private dialog = inject(DialogService);
}

API for dialog — generated from JSDoc in the library source.

API reference for dialog
APIMemberTypeDefaultDescription
DialogServiceopen()(type: Type<unknown>, data?: TData, className?: string, options: { hideOnBackdropClick?: boolean; containerType?: Type<DialogContainer> } = {}) => Observable<TResult | undefined>Opens a component dynamically inside a dialog container. On the server this returns `of(undefined)` and does not touch the DOM.
DialogContainercontextDialogContext<unknown, unknown>The dialog context injected into the hosted component.
DialogContainercontainerSignal<ViewContainerRef>The ViewContainerRef where the dialog content is dynamically rendered.
DialogContainerclassNamestringOptional CSS class string applied to the container wrapper.
base-dialogwidthnumber | stringExplicit width: pixels as a number or any CSS width string (e.g. `'640'`, `'48rem'`).
base-dialogheightnumberExplicit height in pixels. Applied dynamically to the `base-dialog-body` for scrolling.
base-dialog-bodyheightnumber
[base-dialog-close]ariaLabelstringOptional aria-label for accessibility.
[base-dialog-close]typeunknown'button'The native button type. Defaults to 'button'.