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. The dialog box sets view-transition-name: base-dialog for the View Transitions API.

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.

freeView Transitions

Basic Dialog

Basic Dialog example below. Wrap DialogService.open() in document.startViewTransition() — the box already has view-transition-name: base-dialog. Recipe: View Transitions cookbook.

Dialog with Form

Dialog containing form elements and date pickers to gather information.

Confirm Dialog

Use DialogService.confirm() for destructive or important actions. It emits true only when the user confirms; Cancel, Escape, and backdrop click emit false.

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.

Loading and disabled

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

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.

Unit tests: copy DialogHarness with the component and load it with TestbedHarnessEnvironment.documentRootLoader(fixture) (the overlay is appended to document.body). See Getting started — Testing.

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-ng-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.
DialogServiceconfirm()(options: { title: string; description?: string; confirmLabel?: string; cancelLabel?: string; destructive?: boolean; }) => Observable<boolean>Opens a confirm / alert dialog and emits `true` only when the user confirms. Backdrop, Escape, and Cancel emit `false`. SSR-safe: emits `false` on the server 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. Falls back to `provideBaseUiI18n().close`.
[base-dialog-close]typeunknown'button'The native button type. Defaults to 'button'.