Packages
legendary_core
8.9.1
8.12.0
8.11.1
8.11.0
8.10.0
8.9.2
8.9.1
8.5.3
8.5.2
8.5.1
8.5.0
8.4.0
8.3.6
8.3.5
8.3.4
8.3.3
8.3.2
8.3.1
8.3.0
8.2.7
8.2.5
8.2.4
8.2.3
8.2.2
8.2.1
8.2.0
8.1.1
8.1.0
8.0.1
8.0.0
7.17.12
7.17.8
7.17.7
7.17.6
7.17.5
7.17.4
7.17.3
7.17.2
7.17.1
7.17.0
7.16.12
7.16.11
4.5.4
4.0.0
2.12.0
2.11.5
2.6.0
2.4.1
2.4.0
2.3.7
2.1.2
A PETAL-stack batteries-included boilerplate for making Phoenix apps without tedium.
Current section
Files
Jump to
Current section
Files
lib/core_web/views/helpers.ex
defmodule Legendary.CoreWeb.Helpers do
@moduledoc """
HTML helpers for our styled (Tailwind) forms.
"""
use Phoenix.HTML
use Phoenix.Component
alias Phoenix.Flash
alias Legendary.AuthWeb.CoreComponents
import ShorterMaps
defdelegate current_user(a), to: Legendary.AuthWeb.Helpers
defdelegate has_role?(a, b), to: Legendary.AuthWeb.Helpers
def changeset_error_block(changeset) do
assigns = %{changeset: changeset}
~H"""
<CoreComponents.changeset_error_block changeset={@changeset} />
"""
end
def flash_block(%{assigns: assigns}) do
~H"""
<div class="fixed w-full px-4 z-50 mt-20">
<%= [info: "green", error: "red"] |> Enum.map(fn {level, color} -> %>
<%= if Flash.get(@flash, level) do %>
<div class={
"relative bg-#{color}-100 lg:w-1/2 w-full p-5 object-right rounded shadow-xl m-auto mb-5 js-flash"
}>
<div class={"flex justify-between text-#{color}-700"}>
<div class="flex space-x-3">
<div class="flex-1 leading-tight text-sm font-medium">
<%= Flash.get(@flash, level) %>
</div>
</div>
<div class="flex-none js-flash-closer">
×
</div>
</div>
</div>
<% end %>
<% end) %>
</div>
"""
end
def styled_input(form, field, opts \\ [], options \\ nil, block_list \\ []) do
{inner_block, _} = Keyword.pop(block_list, :do, []) || []
{type, rest_opts} = Keyword.pop(opts, :type, input_type(form, field))
{class, rest_opts} = Keyword.pop(rest_opts, :class)
{label_text, rest_opts} = Keyword.pop(rest_opts, :label)
{input_helper, _rest_opts} = Keyword.pop(rest_opts, :input_helper, input_type(form, field))
error_class =
if Keyword.get_values(form.errors || [], field) |> Enum.any?() do
" border border-red-500"
else
""
end
assigns =
~M{class, inner_block, error_class, field, input_helper, label_text, type, options, opts, form}
~H"""
<CoreComponents.styled_input
class={@class}
error_class={@error_class}
field={@field}
input_helper={@input_helper}
label_text={@label_text}
type={@type}
options={@options}
form={@form}
{@opts}
>
<%= @inner_block %>
</CoreComponents.styled_input>
"""
end
def styled_button(inner_block, opts \\ []) do
assigns = ~M{inner_block, opts}
~H"""
<CoreComponents.styled_button {@opts}>
<%= @inner_block %>
</CoreComponents.styled_button>
"""
end
def styled_button_link(inner_block, opts) do
{href, opts} = Keyword.pop(opts, :to, "#")
rest =
opts
|> Enum.into(%{})
|> Map.merge(~M{href})
assigns = ~M{inner_block, rest}
~H"""
<CoreComponents.styled_button_link {@rest}>
<%= @inner_block %>
</CoreComponents.styled_button_link>
"""
end
def styled_button_live_patch(inner_block, opts) do
{to, opts} = Keyword.pop(opts, :to, "#")
assigns = ~M{inner_block, opts, to}
~H"""
<CoreComponents.styled_button_live_patch opts={@opts} to={@to}>
<%= @inner_block %>
</CoreComponents.styled_button_live_patch>
"""
end
def styled_button_live_redirect(inner_block, opts) do
{to, opts} = Keyword.pop(opts, :to, "#")
assigns = ~M{inner_block, opts, to}
~H"""
<CoreComponents.styled_button_live_redirect opts={@opts} to={@to}>
<%= @inner_block %>
</CoreComponents.styled_button_live_redirect>
"""
end
def paginator(~M{first, current_page, last} = assigns) do
pages =
[first, current_page - 1, current_page, current_page + 1, last]
|> Enum.sort()
|> Enum.filter(&(&1 >= first && &1 <= last))
|> Enum.dedup()
assigns = assigns |> Map.put(:pages, pages)
~H"""
<%= for page_number <- @pages do %>
<%= @callback.(@first..@last, page_number) %>
<% end %>
"""
end
def group_rounding_class(
first..last,
current,
[first_class, middle_class, last_class] \\ ["rounded-l", "", "rounded-r"]
) do
cond do
first == last -> "#{first_class} #{last_class}"
current == first -> first_class
current == last -> last_class
true -> middle_class
end
end
@spec floating_form(any, atom | %{action: any}, [{:do, any}, ...]) :: {:safe, [...]}
def floating_form(title, changeset, do: inner_block) do
assigns = ~M{changeset, inner_block, title}
~H"""
<CoreComponents.floating_form changeset={@changeset} title={@title}>
<%= @inner_block %>
</CoreComponents.floating_form>
"""
end
def floating_page_wrapper(do: inner_block) do
assigns = ~M{inner_block}
~H"""
<CoreComponents.floating_page_wrapper>
<%= @inner_block %>
</CoreComponents.floating_page_wrapper>
"""
end
def pow_extension_enabled?(extension) do
{extensions, _rest} = Application.get_env(:core, :pow) |> Keyword.pop(:extensions, [])
Enum.any?(extensions, &(&1 == extension))
end
end