defmodule DaisyUIComponents.Modal do @moduledoc """ Modal component https://daisyui.com/components/modal/ """ use DaisyUIComponents.Component alias Phoenix.LiveView.JS @doc """ Renders a modal. ## Examples <.modal id="confirm-modal"> This is a modal. JS commands may be passed to the `:on_cancel` to configure the closing/cancel event, for example: <.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}> This is another modal. Modal with actions: <.modal id="confirm"> Modal to confirm <:actions> <.button>Confirm <:actions> """ attr :id, :string, required: true attr :open, :boolean, default: false attr :rest, :global attr :on_cancel, JS, default: %JS{} slot :actions, doc: "the slot for showing modal actions" slot :inner_block def modal(assigns) do assigns = join_classes_with_rest(assigns, ["modal modal-bottom sm:modal-middle"]) ~H"""
<.focus_wrap id={"#{@id}-container"} class="modal-box relative" phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")} phx-key="escape" phx-click-away={JS.exec("data-cancel", to: "##{@id}")} >
<%= render_slot(@inner_block) %>
""" end @doc """ Renders a dialog modal. ## Examples <.dialog_modal id="confirm-modal"> <.modal_box> This is a modal JS commands may be passed to the `:on_cancel` to configure the closing/cancel event, for example: <.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}> <.modal_box> This is another modal dialog with actions: <.dialog_modal id="confirm"> <.modal_box> Modal to confirm <:actions> <.button>Confirm <:actions> """ attr :id, :string, required: true attr :class, :string, default: nil attr :open, :boolean, default: false attr :rest, :global attr :on_cancel, JS, default: %JS{} slot :inner_block def dialog_modal(assigns) do ~H""" <%= render_slot(@inner_block) %> """ end attr :modal_id, :string, required: true attr :class, :string, default: nil attr :closable, :boolean, default: true attr :rest, :global slot :inner_block slot :actions, doc: "the slot for showing modal actions" def modal_box(assigns) do ~H""" <.focus_wrap id={"#{@modal_id}-container"} class={["modal-box", @class]} phx-window-keydown={JS.exec("data-cancel", to: "##{@modal_id}")} phx-key="escape" phx-click-away={JS.exec("data-cancel", to: "##{@modal_id}")} >
<%= render_slot(@inner_block) %>
<.modal_action :for={action <- @actions}> <%= render_slot(action) %> """ end attr :class, :string, default: nil slot :inner_block def modal_action(assigns) do ~H"""
<%= render_slot(@inner_block) %>
""" end def show_modal(js \\ %JS{}, id) when is_binary(id) do js |> JS.add_class("modal-open", to: "##{id}") |> JS.focus_first(to: "##{id}-content") end def hide_modal(js \\ %JS{}, id) do js |> JS.remove_class("modal-open", to: "##{id}") |> JS.pop_focus() end end