Dialog
Dialogs built on the native <dialog> element, which replaces Bootstrap’s old modal.
Bootstrap’s dialog docs describe the markup and CSS.
Example
Call show() on the dialog’s template reference. Modal dialogs render in the browser’s top layer, trap focus, and close on Escape. bsDialogClose closes the parent dialog.
<button type="button" bsButton theme="primary" (click)="dialog.show()">Open dialog</button>
<dialog bsDialog #dialog="bsDialog" aria-labelledby="basic-dialog-title">
<div class="dialog-header">
<h2 class="dialog-title" id="basic-dialog-title">Dialog title</h2>
<button bsCloseButton bsDialogClose></button>
</div>
<div class="dialog-body">
<p>This is a native dialog element with the browser’s built-in modal behavior.</p>
</div>
<div class="dialog-footer">
<button type="button" bsButton theme="secondary" bsDialogClose>Close</button>
<button type="button" bsButton theme="primary" bsDialogClose>Save changes</button>
</div>
</dialog>Static backdrop
Set backdrop="static" and [keyboard]="false" to make the user choose an action. The dialog bounces when they click outside it.
<button type="button" bsButton theme="primary" (click)="dialog.show()">Open static dialog</button>
<dialog
bsDialog
#dialog="bsDialog"
backdrop="static"
[keyboard]="false"
aria-labelledby="static-dialog-title">
<div class="dialog-header">
<h2 class="dialog-title" id="static-dialog-title">Static backdrop</h2>
<button bsCloseButton bsDialogClose></button>
</div>
<div class="dialog-body">
<p>I do not close when you click outside me or press Escape.</p>
</div>
<div class="dialog-footer">
<button type="button" bsButton theme="secondary" bsDialogClose>Close</button>
</div>
</dialog>Two-way binding
Bind [(open)] to open the dialog from state. dismissed tells you when the user closed it with Escape or the backdrop.
Result: none
<button type="button" bsButton theme="danger" (click)="confirming.set(true)">Delete file</button>
<p class="mt-3 mb-0">Result: {{ result() }}</p>
<dialog
bsDialog
[(open)]="confirming"
(dismissed)="result.set(`dismissed with ${$event}`)"
aria-labelledby="confirm-dialog-title">
<div class="dialog-header">
<h2 class="dialog-title" id="confirm-dialog-title">Delete file?</h2>
<button type="button" bsCloseButton bsDialogClose></button>
</div>
<div class="dialog-body">
<p>You cannot undo this.</p>
</div>
<div class="dialog-footer">
<button type="button" bsButton theme="secondary" (click)="answer('cancelled')">Cancel</button>
<button type="button" bsButton theme="danger" (click)="answer('deleted')">Delete</button>
</div>
</dialog>Non-modal
Set [modal]="false" to open the dialog inline with show(). The rest of the page stays interactive.
<button type="button" bsButton theme="primary" (click)="dialog.toggle()">
Toggle inline dialog
</button>
<dialog bsDialog #dialog="bsDialog" [modal]="false" aria-labelledby="inline-dialog-title">
<div class="dialog-header">
<h2 class="dialog-title" id="inline-dialog-title">Inline dialog</h2>
<button bsCloseButton bsDialogClose></button>
</div>
<div class="dialog-body">
<p>This dialog opens with <code>show()</code>, so the rest of the page stays interactive.</p>
</div>
</dialog>Opening from code
Inject BsDialogService and call open() with a component or template to show a dialog without writing the <dialog> yourself. Pass the component’s inputs in inputs. The component provides the header, body and footer, and injects BsDialogRef to close() with a value. bsDialogClose dismisses it. The ref’s result promise resolves with that value, or undefined when dismissed, once the dialog is gone. The dialog is labelled by its first .dialog-title.
Result: none
<button type="button" bsButton theme="danger" (click)="remove()">Delete report.pdf</button>
<p class="mt-3 mb-0">Result: {{ result() }}</p>API
BsDialog
Selector: dialog[bsDialog] · Exported as: bsDialog
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Whether the dialog is open. Supports [(open)]. |
modal | boolean | true | Opens as a modal with a backdrop and focus trap. |
backdrop | boolean | 'static' | true | true closes on backdrop click, 'static' bounces, false ignores the click. |
keyboard | boolean | true | Closes the dialog on Escape. |
animation | boolean | true | Animates opening and closing. |
Outputs
| Name | Type | Description |
|---|---|---|
openChange | boolean | Emits when the dialog opens or closes from inside. |
shown | void | Emits after the dialog is shown. |
hidden | void | Emits after the dialog is hidden. |
dismissed | 'escape' | 'backdrop' | Emits when the user dismisses the dialog. |
Methods
| Name | Type | Description |
|---|---|---|
show() | void | Opens the dialog. |
hide() | void | Closes the dialog. |
toggle() | void | Toggles the dialog. |
isOpen | Signal<boolean> | Current open state. |
BsDialogClose
Selector: [bsDialogClose]
BsDialogService
Selector: inject(BsDialogService)
Methods
| Name | Type | Description |
|---|---|---|
open(content, options?) | BsDialogRef | Opens a modal dialog with a component or template. Options: inputs, size ('sm', 'md', 'lg', 'xl' or 'fullscreen'), scrollable, backdrop, keyboard, animation, ariaLabelledBy, ariaLabel, class and injector. For a component, the ref also has componentInstance. |
openDrawer(content, options?) | BsDialogRef | Opens a drawer. Takes the same options without size and scrollable, plus placement and scroll. |
dismissAll() | void | Dismisses every dialog and drawer it opened. |
BsDialogRef
Selector: inject(BsDialogRef)
Methods
| Name | Type | Description |
|---|---|---|
close(value?) | void | Closes the dialog. result resolves with value. |
dismiss() | void | Closes the dialog. result resolves with undefined. |
result | Promise<R | undefined> | Resolves once the dialog is hidden and removed. |