SutraUI.Dialog (Sutra UI v0.3.0)

View Source

A modal dialog component using div-based overlay (screen share compatible).

Uses a div-based implementation instead of native <dialog> element to ensure compatibility with screen sharing tools like Zoom, Google Meet, etc. The native dialog's "top layer" rendering can be invisible during screen shares.

Examples

# Basic confirmation dialog (server-controlled)
<.dialog id="confirm-dialog" show={@show_confirm} on_cancel="close_confirm">
  <:title>Confirm Action</:title>
  <:description>Are you sure you want to proceed?</:description>
  This action cannot be undone.
  <:footer>
    <.button variant="outline" phx-click="close_confirm">Cancel</.button>
    <.button phx-click="confirm">Confirm</.button>
  </:footer>
</.dialog>

# Open by setting assign
def handle_event("open_confirm", _, socket) do
  {:noreply, assign(socket, show_confirm: true)}
end

def handle_event("close_confirm", _, socket) do
  {:noreply, assign(socket, show_confirm: false)}
end

# Or open with JS commands
<.button phx-click={SutraUI.Dialog.show_dialog("confirm-dialog")}>
  Open Dialog
</.button>

# Form inside dialog
<.dialog id="edit-user-dialog" show={@show_edit} on_cancel="cancel_edit">
  <:title>Edit Profile</:title>
  <.simple_form for={@form} phx-submit="save_user">
    <.input field={@form[:name]} label="Name" />
    <.input field={@form[:email]} label="Email" type="email" />
    <:actions>
      <.button type="submit">Save Changes</.button>
    </:actions>
  </.simple_form>
</.dialog>

Opening and Closing

Server-controlled (recommended):

Control visibility via the show assign and handle on_cancel event:

<.dialog id="my-dialog" show={@show_dialog} on_cancel="close_dialog">
  ...
</.dialog>

def handle_event("close_dialog", _, socket) do
  {:noreply, assign(socket, show_dialog: false)}
end

JS commands:

FunctionDescription
show_dialog/1Opens dialog with animation
show_dialog/2Chain with existing JS commands
hide_dialog/1Closes dialog with animation
hide_dialog/2Chain with existing JS commands
# Open on button click
<.button phx-click={SutraUI.Dialog.show_dialog("my-dialog")}>Open</.button>

# Close from inside dialog
<.button phx-click={SutraUI.Dialog.hide_dialog("my-dialog")}>Cancel</.button>

Slots

SlotDescription
titleDialog header title
descriptionExplanatory text below title
inner_blockMain content area
footerAction buttons, typically Cancel/Confirm

Accessibility

  • Uses role="dialog" and aria-modal="true"
  • Escape key closes the dialog
  • Click on backdrop closes the dialog (configurable)
  • Focus is trapped within the dialog when open (via focus_wrap)
  • aria-labelledby links to title
  • aria-describedby links to description

Screen Sharing Compatibility

Unlike the native <dialog> element which renders in the browser's "top layer", this div-based implementation renders in the normal document flow with fixed positioning and z-index. This ensures the dialog is visible when screen sharing.

Summary

Functions

Renders a modal dialog component.

Hides a dialog by ID.

Shows a dialog by ID.

Functions

dialog(assigns)

Renders a modal dialog component.

Attributes

  • id (:string) (required) - Unique identifier for the dialog.
  • show (:boolean) - Whether the dialog is visible. Defaults to false.
  • class (:string) - Additional CSS classes for the dialog panel. Defaults to nil.
  • on_cancel (:any) - Event name (string) or JS commands to execute when dialog is closed. Defaults to nil.
  • close_on_escape (:boolean) - Whether ESC key closes the dialog. Defaults to true.
  • close_on_backdrop (:boolean) - Whether clicking the backdrop closes the dialog. Defaults to true.
  • Global attributes are accepted. Additional HTML attributes.

Slots

  • inner_block (required) - The main dialog content.
  • title - The dialog title.
  • description - The dialog description.
  • footer - Footer content, typically action buttons.

hide_dialog(js \\ %JS{}, id)

Hides a dialog by ID.

Examples

<button phx-click={SutraUI.Dialog.hide_dialog("my-dialog")}>Close</button>

# Chain with other JS commands
<button phx-click={JS.push("save") |> SutraUI.Dialog.hide_dialog("my-dialog")}>
  Save and Close
</button>

show_dialog(js \\ %JS{}, id)

Shows a dialog by ID.

Examples

<button phx-click={SutraUI.Dialog.show_dialog("my-dialog")}>Open</button>

# Chain with other JS commands
<button phx-click={JS.push("load_data") |> SutraUI.Dialog.show_dialog("my-dialog")}>
  Load and Open
</button>