memEx/lib/memex_web/live/live_helpers.ex

136 lines
4.3 KiB
Elixir
Raw Normal View History

2022-07-25 19:31:54 -04:00
defmodule MemexWeb.LiveHelpers do
2022-01-22 20:44:38 -05:00
@moduledoc """
2023-02-04 17:22:06 -05:00
Contains common helper functions for liveviews
2022-01-22 20:44:38 -05:00
"""
use Phoenix.Component
2022-02-25 21:55:27 -05:00
alias Phoenix.LiveView.JS
attr :return_to, :string, required: true
slot(:inner_block)
2021-09-02 23:32:53 -04:00
@doc """
2022-02-25 21:55:27 -05:00
Renders a live component inside a modal.
2021-09-02 23:32:53 -04:00
The rendered modal receives a `:return_to` option to properly update
the URL when the modal is closed.
## Examples
2022-02-25 21:55:27 -05:00
<.modal return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}>
<.live_component
module={<%= inspect context.web_module %>.<%= inspect Module.concat(schema.web_namespace, schema.alias) %>Live.FormComponent}
id={@<%= schema.singular %>.id || :new}
title={@page_title}
action={@live_action}
return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}
<%= schema.singular %>: @<%= schema.singular %>
/>
</.modal>
2021-09-02 23:32:53 -04:00
"""
2022-02-25 21:55:27 -05:00
def modal(assigns) do
~H"""
2022-11-16 21:11:02 -05:00
<.link
id="modal-bg"
2023-01-26 00:28:34 -05:00
patch={@return_to}
2022-11-16 21:11:02 -05:00
class="fade-in fixed z-10 left-0 top-0
2023-02-04 17:22:06 -05:00
w-full h-full overflow-hidden
2023-02-04 11:29:06 -05:00
p-8 flex flex-col justify-center items-center cursor-auto"
2022-11-16 21:11:02 -05:00
style="background-color: rgba(0,0,0,0.4);"
phx-remove={hide_modal()}
>
2022-02-25 21:55:27 -05:00
<span class="hidden"></span>
2022-11-16 21:11:02 -05:00
</.link>
2021-09-02 23:32:53 -04:00
2022-02-25 21:55:27 -05:00
<div
id="modal"
class="fixed z-10 left-0 top-0 pointer-events-none
2022-02-25 21:55:27 -05:00
w-full h-full overflow-hidden
2022-02-25 21:55:27 -05:00
p-4 sm:p-8 flex flex-col justify-center items-center"
>
<div
id="modal-content"
2022-10-26 22:09:49 -04:00
class="fade-in-scale max-w-3xl max-h-3xl relative w-full
2023-02-04 11:29:06 -05:00
pointer-events-auto overflow-hidden
px-8 py-4 sm:py-8 flex flex-col justify-start items-stretch
bg-primary-800 text-primary-400 border-primary-900 border-2 rounded-lg"
2022-02-25 21:55:27 -05:00
>
2022-11-16 21:11:02 -05:00
<.link
patch={@return_to}
id="close"
class="absolute top-8 right-10
2023-02-04 11:29:06 -05:00
text-gray-500 hover:text-gray-800
transition-all duration-500 ease-in-out"
2022-11-16 21:11:02 -05:00
phx-remove={hide_modal()}
>
2022-02-25 21:55:27 -05:00
<i class="fa-fw fa-lg fas fa-times"></i>
2022-11-16 21:11:02 -05:00
</.link>
2022-02-25 21:55:27 -05:00
2023-02-04 17:22:06 -05:00
<div class="overflow-x-hidden overflow-y-auto w-full p-8 flex flex-col space-y-4 justify-start items-stretch">
2022-02-25 21:55:27 -05:00
<%= render_slot(@inner_block) %>
</div>
</div>
</div>
"""
2021-09-02 23:32:53 -04:00
end
2022-01-22 13:01:36 -05:00
2023-02-04 17:22:06 -05:00
defp hide_modal(js \\ %JS{}) do
2022-02-25 21:55:27 -05:00
js
|> JS.hide(to: "#modal", transition: "fade-out")
|> JS.hide(to: "#modal-bg", transition: "fade-out")
|> JS.hide(to: "#modal-content", transition: "fade-out-scale")
2021-09-02 23:32:53 -04:00
end
2023-02-04 17:22:06 -05:00
attr :action, :string, required: true
attr :value, :boolean, required: true
attr :id, :string
slot(:inner_block)
2023-02-04 17:22:06 -05:00
@doc """
A toggle button element that can be directed to a liveview or a
live_component's `handle_event/3`.
## Examples
<.toggle_button action="my_liveview_action" value={@some_value}>
<span>Toggle me!</span>
</.toggle_button>
<.toggle_button action="my_live_component_action" target={@myself} value={@some_value}>
<span>Whatever you want</span>
</.toggle_button>
"""
def toggle_button(assigns) do
assigns = assigns |> assign_new(:id, fn -> assigns.action end)
~H"""
<label for={@id} class="inline-flex relative items-center cursor-pointer">
<input
id={@id}
type="checkbox"
value={@value}
checked={@value}
class="sr-only peer"
aria-labelledby={"#{@id}-label"}
2023-02-04 17:22:06 -05:00
{
if assigns |> Map.has_key?(:target),
do: %{"phx-click": @action, "phx-value-value": @value, "phx-target": @target},
else: %{"phx-click": @action, "phx-value-value": @value}
}
/>
<div class="w-11 h-6 bg-gray-300 rounded-full peer
peer-focus:ring-4 peer-focus:ring-teal-300 dark:peer-focus:ring-teal-800
peer-checked:bg-gray-600
peer-checked:after:translate-x-full peer-checked:after:border-white
after:content-[''] after:absolute after:top-1 after:left-[2px] after:bg-white after:border-gray-300
after:border after:rounded-full after:h-5 after:w-5
after:transition-all after:duration-250 after:ease-in-out
transition-colors duration-250 ease-in-out">
</div>
<span id={"#{@id}-label"} class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">
2023-02-04 17:22:06 -05:00
<%= render_slot(@inner_block) %>
</span>
</label>
"""
end
2021-09-02 23:32:53 -04:00
end