LineaUI.Components.Pagination (linea_ui v0.3.0)

Copy Markdown View Source

LineOne's pagination: a joined bar or divided buttons, rounded or pill, in three sizes.

<.pagination page={@page} total_pages={10} patch={&"/orders?page=#{&1}"} />
<.pagination page={@page} total_pages={10} navigate={&"/orders?page=#{&1}"} divided />
<.pagination page={@page} total_pages={10} on_change="paginate" shape="pill" />

Each page is a link when patch, navigate or href is given: a function from the page number to the path. Otherwise it is a button pushing on_change with %{"page" => "3"} (to target when given). Pages far from the current one collapse into an ellipsis: siblings pages are kept on each side of the current one and boundaries at each end.

A list footer: total_entries and page_size add the "Showing 1–15 of 128" summary on the left (and work out total_pages), page_sizes a rows-per-page select pushing on_page_size.

<.pagination
  page={@page}
  page_size={@per_page}
  total_entries={@total}
  page_sizes={[15, 30, 50]}
  on_change="paginate"
  on_page_size="per_page"
  summary="Mostrando %{first}–%{last} de %{total}"
  page_size_label="%{size} / página"
/>

Summary

Functions

Renders the page links between a previous and a next arrow.

The pages to show around page out of total: numbers, with :gap where pages are left out.

Functions

pagination(assigns)

Renders the page links between a previous and a next arrow.

<.pagination page={@page} total_pages={@total} patch={&"/orders?page=#{&1}"} />
<.pagination page={@page} total_pages={@total} on_change="paginate" target={@myself} />

With on_change="paginate" every page and arrow is a button pushing "paginate" with %{"page" => "3"} (the page as a string):

def handle_event("paginate", %{"page" => page}, socket),
  do: {:noreply, assign(socket, page: String.to_integer(page))}

The arrow at either end and the ellipsis are inert <span>s.

With total_entries or page_sizes the bar becomes a footer row: the summary (role="status") on the left, the select and the pages on the right. The select sits in its own <form> and pushes on_page_size with %{"page_size" => "30"} (to target), so do not put the pagination inside another form.

def handle_event("per_page", %{"page_size" => size}, socket),
  do: {:noreply, assign(socket, per_page: String.to_integer(size), page: 1)}

Attributes

  • page (:integer) (required) - The current page, from 1.

  • total_pages (:integer) - How many pages there are. Worked out from total_entries and page_size when not given. Defaults to nil.

  • total_entries (:integer) - Rows across every page; shows the summary. Defaults to nil.

  • page_size (:integer) - Rows per page; the select's current value. Defaults to nil.

  • page_sizes (:list) - Options of the rows-per-page select. Defaults to [].

  • on_page_size (:any) - Event name or %JS{} of the select's form, pushed with %{"page_size" => "30"}. Defaults to nil.

  • summary (:string) - The summary text; %{first}, %{last} and %{total} are replaced. Defaults to "Showing %{first}–%{last} of %{total}".

  • page_size_label (:string) - Text of each select option; %{size} is replaced. Defaults to "%{size} / page".

  • page_size_aria (:string) - aria-label of the select. Defaults to "Rows per page".

  • siblings (:integer) - Pages kept on each side of the current one. Defaults to 1.

  • boundaries (:integer) - Pages kept at each end. Defaults to 1.

  • patch (:any) - A function from a page number to a path to patch to. Defaults to nil.

  • navigate (:any) - A function from a page number to a path to navigate to. Defaults to nil.

  • href (:any) - A function from a page number to a URL. Defaults to nil.

  • on_change (:any) - Used when no link function is given: an event name pushed with %{"page" => "3"}, or a %JS{} run on click (its JS.push carries the same page value).

    Defaults to nil.

  • target (:any) - The phx-target of on_change. Defaults to nil.

  • divided (:boolean) - Separate buttons instead of one joined bar. Defaults to false.

  • shape (:string) - Defaults to "rounded". Must be one of "rounded", or "pill".

  • size (:string) - Defaults to "md". Must be one of "sm", "md", or "lg".

  • arrows (:boolean) - Show the previous and next arrows. Defaults to true.

  • prev_label (:string) - Defaults to "Previous page".

  • next_label (:string) - Defaults to "Next page".

  • class (:any) - Defaults to nil.

  • Global attributes are accepted.

window(page, total, siblings, boundaries)

@spec window(pos_integer(), pos_integer(), non_neg_integer(), non_neg_integer()) :: [
  pos_integer() | :gap
]

The pages to show around page out of total: numbers, with :gap where pages are left out.

iex> LineaUI.Components.Pagination.window(5, 10, 1, 1)
[1, :gap, 4, 5, 6, :gap, 10]