Modal

Renders a modal dialog for content such as forms and informational panels.

Read more Read less

This component is appropriate for non-critical interactions. For dialogs requiring immediate user response, such as confirmations or warnings, use .alert_dialog/1 instead.

Usage

There are two primary ways to manage the display of the modal: via URL state or by setting and removing the open attribute.

With URL

To toggle the modal visibility based on the URL:

  1. Use the :if attribute to conditionally render the modal when a specific live action matches.
  2. Set the on_cancel attribute to patch back to the original URL when the user chooses to close the modal.
  3. Set the open attribute to declare the modal’s initial visibility state.

Example

<.modal
  :if={@live_action == :show}
  id="pet-modal"
  on_cancel={JS.patch(~p"/pets")}
  open
>
  <:title>Show pet</:title>
  <p>My pet is called Johnny.</p>
  <:footer>
    <.link phx-click={JS.exec("data-cancel", to: "#pet-modal")}>
      Close
    </.link>
  </:footer>
</.modal>

To open the modal, patch or navigate to the URL associated with the live action.

<.link patch={~p"/pets/#{@id}"}>show</.link>

Without URL

To toggle the modal visibility dynamically with the open attribute:

  1. Omit the open attribute in the template.
  2. Use the show_modal/1 and hide_modal/1 functions to change the visibility.

Example

<.modal id="pet-modal">
  <:title>Show pet</:title>
  <p>My pet is called Johnny.</p>
  <:footer>
    <.link phx-click={JS.exec("data-cancel", to: "#pet-modal")}>
      Close
    </.link>
  </:footer>
</.modal>

To open modal, use the show_modal/1 function.

<.button
  phx-click={Doggo.show_modal("pet-modal")}
  aria-haspopup="dialog"
>
  show
</.button>

CSS

To hide the modal when the open attribute is not set, use the following CSS styles:

dialog.modal:not([open]),
dialog.modal[open="false"] {
  display: none;
}

Semantics

While the showModal() JavaScript function is typically recommended for managing modal dialog semantics, this component utilizes the open attribute to control visibility. This approach is chosen to eliminate the need for library consumers to add additional JavaScript code. To ensure proper modal semantics, the aria-modal attribute is added to the dialog element.

Attribute Type Documentation Default Value
class :any Any additional classes to be added. Variations of the component should be expressed via modifier attributes, and it is preferable to use styles on the parent container to arrange components on the page, but if you have to, you can use this attribute to pass additional utility classes to the component. The value can be a string or a list of strings. []
close_label :string Aria label for the close button. "Close"
dismissable :boolean When set to `true`, the dialog can be dismissed by clicking a close button or by pressing the escape key. true
Required id * :string
on_cancel %JS{} An additional `Phoenix.LiveView.JS` command to execute when the dialog is canceled. This command is executed in addition to closing the dialog. If you only want the dialog to be closed, you don't have to set this attribute. %Phoenix.LiveView.JS{ops: []}
open :boolean Initializes the modal as open. false
rest :global Any additional HTML attributes.
close :slot The content for the 'close' link. Defaults to the word 'close'.
footer :slot
<:footer>
  <button phx-click={JS.exec("data-cancel", to: "#modal-single-default")}>
    Close
  </button>
</:footer>
Required inner_block * :slot The modal body.
<p>My pet is called Johnny.</p>
Required title * :slot
<:title>Show pet</:title>