ngx-dialog-forge
June 26, 2026 · View on GitHub
A declarative, signals-native Angular dialog library built on the native <dialog> element.
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, andinertmanagement 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-themeattribute; no Angular input required - Per-instance overrides —
closeButton,closeOnBackdrop,closeOnEscape, andsizecan all be overridden per dialog - Global config — set defaults once with
provideDialog()inapp.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
| Input | Type | Default | Description |
|---|---|---|---|
open | model<boolean> | false | Two-way binding for the open state |
title | string | — | Dialog heading text |
closeButton | boolean | from config / true | Show the × close button in the header |
closeOnBackdrop | boolean | from config / true | Close when the backdrop is clicked |
closeOnEscape | boolean | from config / true | Close on the Escape key |
size | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Max-width preset |
actions | NgxDialogAction[] | [] | Shorthand action buttons (alternative to the slot) |
Outputs
| Output | Payload | Description |
|---|---|---|
action | string | Emits the action type when a button is clicked ('confirm', 'cancel', or custom) |
opened | void | Fires after showModal() is called |
closed | void | Fires after the dialog closes (any cause) |
Directives
| Selector | Description |
|---|---|
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.
| Property | Default | Description |
|---|---|---|
--ngx-dialog-bg | #ffffff | Dialog background |
--ngx-dialog-border | none | Dialog outline border |
--ngx-dialog-border-radius | 8px | Corner radius |
--ngx-dialog-shadow | medium drop shadow | Box shadow |
--ngx-dialog-border-color | rgba(0,0,0,.08) | Header / footer divider colour |
--ngx-dialog-backdrop-color | rgba(0,0,0,.5) | ::backdrop colour |
--ngx-dialog-padding | 1.25rem 1.5rem | Fallback padding for header and body |
--ngx-dialog-header-bg | transparent | Header background |
--ngx-dialog-header-padding | inherits --ngx-dialog-padding | Header padding |
--ngx-dialog-title-color | inherit | Title text colour |
--ngx-dialog-title-size | 1.125rem | Title font size |
--ngx-dialog-title-weight | 600 | Title font weight |
--ngx-dialog-body-padding | inherits --ngx-dialog-padding | Body padding |
--ngx-dialog-body-color | inherit | Body text colour |
--ngx-dialog-footer-bg | transparent | Footer background |
--ngx-dialog-footer-padding | 1rem 1.5rem | Footer padding |
--ngx-dialog-confirm-bg | #3b82f6 | Confirm button background |
--ngx-dialog-confirm-color | #ffffff | Confirm button text |
--ngx-dialog-confirm-border | matches bg | Confirm button border |
--ngx-dialog-confirm-shadow | none | Confirm button box-shadow |
--ngx-dialog-cancel-bg | transparent | Cancel button background |
--ngx-dialog-cancel-color | #374151 | Cancel button text |
--ngx-dialog-cancel-border | #d1d5db | Cancel button border |
--ngx-dialog-btn-radius | 6px | Button corner radius |
--ngx-dialog-btn-padding | 0.5rem 1.25rem | Button padding |
--ngx-dialog-btn-font-size | 0.875rem | Button font size |
--ngx-dialog-btn-font-weight | 500 | Button font weight |
--ngx-dialog-btn-letter-spacing | normal | Button letter spacing |
--ngx-dialog-close-btn-color | #6b7280 | × button colour |
--ngx-dialog-close-btn-radius | 4px | × button corner radius |
--ngx-dialog-close-btn-hover-bg | rgba(0,0,0,.06) | × button hover background |
--ngx-dialog-close-btn-hover-color | #111827 | × button hover colour |
--ngx-dialog-focus-ring | #3b82f6 | Focus outline colour |
--ngx-dialog-width-sm | 360px | Width for size="sm" |
--ngx-dialog-width-md | 540px | Width for size="md" |
--ngx-dialog-width-lg | 720px | Width for size="lg" |
--ngx-dialog-width-xl | 960px | Width 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