Created
February 2, 2023 14:18
-
-
Save cblavier/50756b9e6585cf1a4d6d8da97fb69562 to your computer and use it in GitHub Desktop.
Phoenix pagination components
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule ReadableWeb.Pagination do | |
use Phoenix.Component | |
attr :page, :integer, required: true | |
attr :page_count, :integer, required: true | |
attr :path, :string, required: true | |
def pagination(assigns) do | |
~H""" | |
<ul class="inline-flex items-center h-8"> | |
<li class="h-full"> | |
<.link patch={previous_page(@path, @page)} class={[item_class(), "rounded-l-md"]}> | |
<span class="sr-only">Previous</span> | |
<i class="fa fa-chevron-left fa-xs" /> | |
</.link> | |
</li> | |
<%= if @page < 3 do %> | |
<li :for={i <- 1..(@page - 1)} :if={i > 0 && i < @page} class="h-full"> | |
<.link patch={page_path(@path, i)} class={item_class()}><%= i %></.link> | |
</li> | |
<% else %> | |
<li class="h-full"> | |
<.link patch={page_path(@path, 1)} class={item_class()}>1</.link> | |
</li> | |
<li class="h-full"> | |
<span class={item_class()}>...</span> | |
</li> | |
<% end %> | |
<li class="h-full"> | |
<.link patch={page_path(@path, @page)} class={[item_class(), active_item_class()]}> | |
<%= @page %> | |
</.link> | |
</li> | |
<%= if @page_count - @page < 2 do %> | |
<li :for={i <- (@page + 1)..@page_count} :if={i > @page && i <= @page_count} class="h-full"> | |
<.link patch={page_path(@path, i)} class={item_class()}><%= i %></.link> | |
</li> | |
<% else %> | |
<li class="h-full"> | |
<span class={item_class()}>...</span> | |
</li> | |
<li class="h-full"> | |
<.link patch={page_path(@path, @page_count)} class={item_class()}> | |
<%= @page_count %> | |
</.link> | |
</li> | |
<% end %> | |
<li class="h-full"> | |
<.link | |
patch={next_page(@path, @page, @page_count)} | |
class={[item_class(), "border-r rounded-r-md"]} | |
> | |
<span class="sr-only">Next</span> | |
<i class="fa fa-chevron-right fa-xs" /> | |
</.link> | |
</li> | |
</ul> | |
""" | |
end | |
defp previous_page(path, 1), do: page_path(path, 1) | |
defp previous_page(path, page), do: page_path(path, page - 1) | |
defp next_page(path, page, page), do: page_path(path, page) | |
defp next_page(path, page, _page_count), do: page_path(path, page + 1) | |
defp page_path(path, 1), do: path | |
defp page_path(path, page) do | |
if String.contains?(path, "?") do | |
"#{path}&page=#{page}" | |
else | |
"#{path}?page=#{page}" | |
end | |
end | |
defp item_class do | |
"flex justify-center items-center h-full px-3 border-t border-b border-l border-secondary-300 hover:bg-primary-100 hover:text-primary-600 text-sm font-medium" | |
end | |
defp active_item_class do | |
"bg-primary-100 text-primary-600 font-semibold" | |
end | |
attr :page, :integer, required: true | |
attr :page_size, :integer, required: true | |
attr :entry_count, :integer, required: true | |
def entry_count(assigns) do | |
~H""" | |
<div class="text-secondary-500 text-sm"> | |
<span>Showing</span> | |
<span class="text-secondary-900 font-medium"> | |
<%= (@page - 1) * @page_size + 1 %> - <%= min(@page * @page_size, @entry_count) %> | |
</span> | |
<span>of</span> | |
<span class="text-secondary-900 font-medium"><%= @entry_count %></span> | |
</div> | |
""" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment