Skip to main content

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.

Dialog title

This is a native dialog element with the browser’s built-in modal behavior.

HTML
<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.

Static backdrop

I do not close when you click outside me or press Escape.

HTML
<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

Delete file?

You cannot undo this.

<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.

Inline dialog

This dialog opens with show(), so the rest of the page stays interactive.

HTML
<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

NameTypeDefaultDescription
openbooleanfalseWhether the dialog is open. Supports [(open)].
modalbooleantrueOpens as a modal with a backdrop and focus trap.
backdropboolean | 'static'truetrue closes on backdrop click, 'static' bounces, false ignores the click.
keyboardbooleantrueCloses the dialog on Escape.
animationbooleantrueAnimates opening and closing.

Outputs

NameTypeDescription
openChangebooleanEmits when the dialog opens or closes from inside.
shownvoidEmits after the dialog is shown.
hiddenvoidEmits after the dialog is hidden.
dismissed'escape' | 'backdrop'Emits when the user dismisses the dialog.

Methods

NameTypeDescription
show()voidOpens the dialog.
hide()voidCloses the dialog.
toggle()voidToggles the dialog.
isOpenSignal<boolean>Current open state.

BsDialogClose

Selector: [bsDialogClose]

BsDialogService

Selector: inject(BsDialogService)

Methods

NameTypeDescription
open(content, options?)BsDialogRefOpens 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?)BsDialogRefOpens a drawer. Takes the same options without size and scrollable, plus placement and scroll.
dismissAll()voidDismisses every dialog and drawer it opened.

BsDialogRef

Selector: inject(BsDialogRef)

Methods

NameTypeDescription
close(value?)voidCloses the dialog. result resolves with value.
dismiss()voidCloses the dialog. result resolves with undefined.
resultPromise<R | undefined>Resolves once the dialog is hidden and removed.