Current section

Files

Jump to
corex lib components pagination connect.ex
Raw

lib/components/pagination/connect.ex

defmodule Corex.Pagination.Connect do
@moduledoc false
alias Corex.Pagination.Anatomy.{NextTrigger, PrevTrigger, Props, Root, SsrEllipsis, SsrPageItem}
alias Corex.Pagination.Translation, as: PaginationTranslation
alias Corex.Selectors
alias Phoenix.LiveView.JS
import Corex.Helpers,
only: [get_boolean: 1, maybe_put_data_dir_from: 2, maybe_put_dir_from: 2]
@spec props(Props.t()) :: map()
def props(assigns) do
%{
"id" => assigns.id,
"data-count" => to_string(assigns.count),
"data-page" => if(assigns.controlled, do: to_string(assigns.page), else: nil),
"data-default-page" => if(assigns.controlled, do: nil, else: to_string(assigns.page)),
"data-page-size" =>
if(assigns.controlled_page_size, do: to_string(assigns.page_size), else: nil),
"data-default-page-size" =>
if(assigns.controlled_page_size, do: nil, else: to_string(assigns.page_size)),
"data-controlled" => get_boolean(assigns.controlled),
"data-controlled-page-size" => get_boolean(assigns.controlled_page_size),
"data-sibling-count" => to_string(assigns.sibling_count),
"data-boundary-count" => to_string(assigns.boundary_count),
"data-type" => assigns.type,
"data-to" => link_base_to(assigns),
"data-page-param" => assigns.page_param,
"data-page-size-param" => assigns.page_size_param,
"data-redirect" => assigns.redirect,
"data-on-page-change" => assigns.on_page_change,
"data-on-page-change-client" => assigns.on_page_change_client,
"data-on-page-size-change" => assigns.on_page_size_change,
"data-on-page-size-change-client" => assigns.on_page_size_change_client,
"data-translation" => translation_json(assigns)
}
|> maybe_put_data_dir_from(assigns)
end
defp link_base_to(%{to: to}) when is_binary(to) do
if Corex.Url.allowed_href?(to), do: to
end
defp link_base_to(_), do: nil
defp translation_json(assigns) do
case Map.get(assigns, :translation) do
%PaginationTranslation{} = t ->
t
|> PaginationTranslation.to_camel_map()
|> Enum.reject(fn {_, v} -> v in [nil, ""] end)
|> Map.new()
|> then(fn
m when map_size(m) == 0 -> nil
m -> Corex.Dataset.encode_json(m)
end)
_ ->
nil
end
end
@spec root(Root.t()) :: map()
def root(assigns) do
%{
"data-scope" => "pagination",
"data-part" => "root",
"id" => "pagination:#{assigns.id}"
}
|> maybe_put_dir_from(assigns)
|> maybe_put_aria_label(root_aria_label(assigns.id, assigns.aria_label))
end
def ignore_root(%Root{} = assigns) do
JS.ignore_attributes(Root.ignored_attrs(), to: Selectors.css_id("pagination:#{assigns.id}"))
end
@spec prev_trigger(PrevTrigger.t()) :: map()
def prev_trigger(assigns) do
%{
"data-scope" => "pagination",
"data-part" => "prev-trigger",
"data-pagination-part" => "prev",
"type" => if(assigns.tag == "link", do: nil, else: "button"),
"id" => "pagination:#{assigns.id}:prev"
}
|> maybe_put_dir_from(assigns)
|> maybe_put_trigger_aria_label(assigns.aria_label, assigns.disabled, assigns.tag)
|> maybe_put_data_disabled(assigns.disabled)
|> maybe_put_disabled(assigns.disabled and assigns.tag == "button")
|> maybe_put_href(assigns.href)
|> maybe_put_phx_link(assigns.tag, assigns.redirect)
end
def ignore_prev_trigger(%PrevTrigger{} = assigns) do
JS.ignore_attributes(PrevTrigger.ignored_attrs(),
to: Selectors.css_id("pagination:#{assigns.id}:prev")
)
end
@spec next_trigger(NextTrigger.t()) :: map()
def next_trigger(assigns) do
%{
"data-scope" => "pagination",
"data-part" => "next-trigger",
"data-pagination-part" => "next",
"type" => if(assigns.tag == "link", do: nil, else: "button"),
"id" => "pagination:#{assigns.id}:next"
}
|> maybe_put_dir_from(assigns)
|> maybe_put_trigger_aria_label(assigns.aria_label, assigns.disabled, assigns.tag)
|> maybe_put_data_disabled(assigns.disabled)
|> maybe_put_disabled(assigns.disabled and assigns.tag == "button")
|> maybe_put_href(assigns.href)
|> maybe_put_phx_link(assigns.tag, assigns.redirect)
end
def ignore_next_trigger(%NextTrigger{} = assigns) do
JS.ignore_attributes(NextTrigger.ignored_attrs(),
to: Selectors.css_id("pagination:#{assigns.id}:next")
)
end
@spec ssr_page_item(SsrPageItem.t()) :: map()
def ssr_page_item(%SsrPageItem{} = a) do
%{
"data-scope" => "pagination",
"data-part" => "item",
"data-pagination-part" => "page",
"data-index" => to_string(a.page),
"id" => "pagination:#{a.id}:item:#{a.page}",
"type" => if(a.tag == "link", do: nil, else: "button")
}
|> maybe_put_dir_from(a)
|> maybe_put_data_selected(a.selected)
|> maybe_put_aria_current(a.selected)
|> maybe_put_aria_label(a.aria_label)
|> maybe_put_href(a.href)
|> maybe_put_phx_link(a.tag, a.redirect)
end
def ignore_ssr_page_item(%SsrPageItem{} = a) do
JS.ignore_attributes(SsrPageItem.ignored_attrs(),
to: Selectors.css_id("pagination:#{a.id}:item:#{a.page}")
)
end
@spec ssr_ellipsis(SsrEllipsis.t()) :: map()
def ssr_ellipsis(%SsrEllipsis{} = a) do
%{
"data-scope" => "pagination",
"data-part" => "ellipsis",
"data-pagination-part" => "page",
"id" => "pagination:#{a.id}:ellipsis:#{a.index}"
}
|> maybe_put_dir_from(a)
end
def ignore_ssr_ellipsis(%SsrEllipsis{} = a) do
JS.ignore_attributes(SsrEllipsis.ignored_attrs(),
to: Selectors.css_id("pagination:#{a.id}:ellipsis:#{a.index}")
)
end
defp maybe_put_aria_label(attrs, nil), do: attrs
defp maybe_put_aria_label(attrs, label), do: Map.put(attrs, "aria-label", label)
defp maybe_put_trigger_aria_label(attrs, _label, true, "link"), do: attrs
defp maybe_put_trigger_aria_label(attrs, label, _, _), do: maybe_put_aria_label(attrs, label)
defp root_aria_label(id, label) when is_binary(label) and label != "", do: "#{label} (#{id})"
defp root_aria_label(id, _), do: "Pagination (#{id})"
defp maybe_put_data_disabled(attrs, true), do: Map.put(attrs, "data-disabled", "")
defp maybe_put_data_disabled(attrs, false), do: attrs
defp maybe_put_disabled(attrs, true), do: Map.put(attrs, "disabled", "")
defp maybe_put_disabled(attrs, false), do: attrs
defp maybe_put_href(attrs, nil), do: attrs
defp maybe_put_href(attrs, href), do: Map.put(attrs, "href", href)
defp maybe_put_data_selected(attrs, true), do: Map.put(attrs, "data-selected", "")
defp maybe_put_data_selected(attrs, false), do: attrs
defp maybe_put_aria_current(attrs, true), do: Map.put(attrs, "aria-current", "page")
defp maybe_put_aria_current(attrs, false), do: attrs
defp maybe_put_phx_link(attrs, "link", "patch") do
attrs
|> Map.put("data-phx-link", "patch")
|> Map.put("data-phx-link-state", "push")
end
defp maybe_put_phx_link(attrs, "link", "navigate") do
attrs
|> Map.put("data-phx-link", "redirect")
|> Map.put("data-phx-link-state", "push")
end
defp maybe_put_phx_link(attrs, _tag, _redirect), do: attrs
end