ModalStack

A single, stackable modal container for Phoenix LiveView. One stack per page — only one modal is visible at a time — built on a struct in assigns + a function component + a LiveView hook (no live_component, no hidden process).

Installation

def deps do
[{:modal_stack, "~> 0.1"}]
end

Tailwind

The default chrome ships Tailwind utility classes, so your app must include the package in its Tailwind content scan. For Tailwind v4, add to your app.css:

@source "../../deps/modal_stack/lib";

(Adjust the relative path to point at deps/modal_stack/lib from your CSS file.)

Usage

def mount(_params, _session, socket) do
{:ok, ModalStack.attach(socket)}
end
def handle_event("delete", _p, socket), do: {:noreply, ModalStack.push(socket, :confirm_delete)}
<ModalStack.modal_stack stack={@modal_stack}>
<:modal name={:confirm_delete} on_cancel={JS.push("delete_cancelled")}>
<p>Are you sure?</p>
<.button phx-click="really_delete">Delete</.button>
</:modal>
</ModalStack.modal_stack>

The close button, Escape, and click-away pop the stack automatically — no close handler needed. on_cancel is an optional extra side-effect.

API