ngx-dialog-forge

June 26, 2026 · View on GitHub

A declarative, signals-native Angular dialog library built on the native <dialog> element.

CI npm license

Live demo →


Features

  • Declarative API — place <ngx-dialog> directly in your template, no service calls
  • Signals-first — two-way binding via model(), input(), output() throughout; OnPush everywhere
  • Native <dialog> element — free focus trapping, backdrop, and inert management from the browser
  • Zero runtime dependencies — no CDK, no third-party packages
  • Flexible actions — declarative slot (ng-template ngxDialogActions) or shorthand [actions] input
  • CSS-only theming — three ready-made themes (Material, Bootstrap, PrimeNG) activated via a single data-ngx-theme attribute; no Angular input required
  • Per-instance overridescloseButton, closeOnBackdrop, closeOnEscape, and size can all be overridden per dialog
  • Global config — set defaults once with provideDialog() in app.config.ts
  • SSR-compatible — all DOM calls are guarded with isPlatformBrowser

Requirements

  • Angular 22+

Installation

pnpm add ngx-dialog-forge
# or
npm install ngx-dialog-forge

Setup

1. Register global defaults (optional)

// app.config.ts
import { provideDialog } from 'ngx-dialog-forge';

export const appConfig: ApplicationConfig = {
  providers: [
    provideDialog({
      closeButton: true,
      closeOnBackdrop: true,
      closeOnEscape: true,
    }),
  ],
};

2. Load a theme

Import one of the provided SCSS partials in your global stylesheet and set data-ngx-theme on an ancestor element (typically <body>):

// styles.scss
@use 'ngx-dialog-forge/themes/material';
@use 'ngx-dialog-forge/themes/bootstrap';
@use 'ngx-dialog-forge/themes/primeng';
<body data-ngx-theme="material">...</body>

Switching the attribute value at runtime changes the active theme instantly — no JavaScript style injection required.


Usage

Basic dialog

import { NgxDialogComponent } from 'ngx-dialog-forge';

@Component({
  imports: [NgxDialogComponent],
  template: `
    <button (click)="open.set(true)">Open</button>

    <ngx-dialog [(open)]="open" title="Hello">
      <p>Dialog body content.</p>
    </ngx-dialog>
  `,
})
export class MyComponent {
  open = signal(false);
}

Declarative actions slot

Use ng-template ngxDialogActions with ngxDialogCancel / ngxDialogConfirm marker directives. The dialog closes and emits through (action) automatically when either is clicked.

import {
  NgxDialogComponent,
  NgxDialogActionsDirective,
  NgxDialogCancelDirective,
  NgxDialogConfirmDirective,
} from 'ngx-dialog-forge';

@Component({
  imports: [NgxDialogComponent, NgxDialogActionsDirective, NgxDialogCancelDirective, NgxDialogConfirmDirective],
  template: `
    <ngx-dialog [(open)]="open" title="Delete item?" (action)="onAction($event)">
      <p>This action cannot be undone.</p>

      <ng-template ngxDialogActions>
        <button type="button" ngxDialogCancel>Cancel</button>
        <button type="button" ngxDialogConfirm>Delete</button>
      </ng-template>
    </ngx-dialog>
  `,
})
export class MyComponent {
  open = signal(false);

  onAction(type: string): void {
    console.log(type); // 'confirm' | 'cancel'
  }
}

Actions via [actions] input

Shorthand for simple confirm / cancel flows without a template slot:

<ngx-dialog
  [(open)]="open"
  title="Confirm"
  [actions]="[{ label: 'Cancel', type: 'cancel' }, { label: 'OK', type: 'confirm' }]"
  (action)="onAction($event)">
  <p>Are you sure?</p>
</ngx-dialog>

Per-instance overrides

Every option from provideDialog() can be overridden per dialog:

<ngx-dialog
  [(open)]="open"
  title="Important"
  [closeOnBackdrop]="false"
  [closeOnEscape]="false"
  [closeButton]="true"
  size="sm">
  <p>Only the X button closes this.</p>
</ngx-dialog>

NgxDialogComponent API

Inputs

InputTypeDefaultDescription
openmodel<boolean>falseTwo-way binding for the open state
titlestringDialog heading text
closeButtonbooleanfrom config / trueShow the × close button in the header
closeOnBackdropbooleanfrom config / trueClose when the backdrop is clicked
closeOnEscapebooleanfrom config / trueClose on the Escape key
size'sm' | 'md' | 'lg' | 'xl''md'Max-width preset
actionsNgxDialogAction[][]Shorthand action buttons (alternative to the slot)

Outputs

OutputPayloadDescription
actionstringEmits the action type when a button is clicked ('confirm', 'cancel', or custom)
openedvoidFires after showModal() is called
closedvoidFires after the dialog closes (any cause)

Directives

SelectorDescription
ng-template[ngxDialogActions]Marks an ng-template as the actions slot
[ngxDialogConfirm]Marks a button as the confirm action — emits 'confirm' and closes the dialog on click
[ngxDialogCancel]Marks a button as the cancel action — emits 'cancel' and closes the dialog on click

provideDialog() options

interface NgxDialogConfig {
  closeButton?: boolean;      // default: true
  closeOnBackdrop?: boolean;  // default: true
  closeOnEscape?: boolean;    // default: true
}

CSS custom properties

Override any of these on dialog.ngx-dialog (or a parent) to customise the look without writing a full theme.

PropertyDefaultDescription
--ngx-dialog-bg#ffffffDialog background
--ngx-dialog-bordernoneDialog outline border
--ngx-dialog-border-radius8pxCorner radius
--ngx-dialog-shadowmedium drop shadowBox shadow
--ngx-dialog-border-colorrgba(0,0,0,.08)Header / footer divider colour
--ngx-dialog-backdrop-colorrgba(0,0,0,.5)::backdrop colour
--ngx-dialog-padding1.25rem 1.5remFallback padding for header and body
--ngx-dialog-header-bgtransparentHeader background
--ngx-dialog-header-paddinginherits --ngx-dialog-paddingHeader padding
--ngx-dialog-title-colorinheritTitle text colour
--ngx-dialog-title-size1.125remTitle font size
--ngx-dialog-title-weight600Title font weight
--ngx-dialog-body-paddinginherits --ngx-dialog-paddingBody padding
--ngx-dialog-body-colorinheritBody text colour
--ngx-dialog-footer-bgtransparentFooter background
--ngx-dialog-footer-padding1rem 1.5remFooter padding
--ngx-dialog-confirm-bg#3b82f6Confirm button background
--ngx-dialog-confirm-color#ffffffConfirm button text
--ngx-dialog-confirm-bordermatches bgConfirm button border
--ngx-dialog-confirm-shadownoneConfirm button box-shadow
--ngx-dialog-cancel-bgtransparentCancel button background
--ngx-dialog-cancel-color#374151Cancel button text
--ngx-dialog-cancel-border#d1d5dbCancel button border
--ngx-dialog-btn-radius6pxButton corner radius
--ngx-dialog-btn-padding0.5rem 1.25remButton padding
--ngx-dialog-btn-font-size0.875remButton font size
--ngx-dialog-btn-font-weight500Button font weight
--ngx-dialog-btn-letter-spacingnormalButton letter spacing
--ngx-dialog-close-btn-color#6b7280× button colour
--ngx-dialog-close-btn-radius4px× button corner radius
--ngx-dialog-close-btn-hover-bgrgba(0,0,0,.06)× button hover background
--ngx-dialog-close-btn-hover-color#111827× button hover colour
--ngx-dialog-focus-ring#3b82f6Focus outline colour
--ngx-dialog-width-sm360pxWidth for size="sm"
--ngx-dialog-width-md540pxWidth for size="md"
--ngx-dialog-width-lg720pxWidth for size="lg"
--ngx-dialog-width-xl960pxWidth for size="xl"

Contributing

Pull requests are welcome. For significant changes please open an issue first.

git clone https://github.com/HoplaGeiss/ngx-dialog-forge.git
cd ngx-dialog-forge
pnpm install
pnpm start   # starts the demo app at localhost:4200

License

MIT