Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Table #47

Merged
merged 12 commits into from
Apr 16, 2020
45 changes: 45 additions & 0 deletions example/lib/example_web/templates/page/index.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -327,5 +327,50 @@ airports = [{"Louis Armstrong", "MSY"}, {"John F. Kennedy", "JFK"}]

</section>

<section>
<%= row do %>
<%= col do %>
<h3>Table</h3>
<% end %>

<%= col do %>
<%= table do %>
<%= table_head do %>
<%= table_row do %>
<%= table_header do: "ID" %>
<%= table_header do: "First Name" %>
<%= table_header do: "Last Name" %>
<% end %>
<% end %>
<%= table_body do %>
<%= for n <- 0..9 do %>
<%= table_row do %>
<%= table_data do: n %>
<%= table_data do: "John" %>
<%= table_data do: "Doe#{n}" %>
<% end %>
<% end %>
<%= table_row do %>
<%= table_data do: "10" %>
<%= table_data do: "Jane" %>
<%= table_data do: "Doe" %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
</section>

<section>
<%= row do %>
<%= col do %>
<h3>Pagination</h3>
<% end %>

<%= col do %>
<%= pagination(@conn, Routes.page_path(@conn, :index), 5, 10) %>
<% end %>
<% end %>
</section>
<% end %>
<% end %>
16 changes: 15 additions & 1 deletion lib/harmonium.ex
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ defmodule Harmonium do
defp error_helper(error) do
case Application.get_env(:harmonium, :error_helper, nil) do
nil ->
{message, opts} = error
{message, _opts} = error
message

error_helper ->
Expand Down Expand Up @@ -669,6 +669,20 @@ defmodule Harmonium do
end
end

defdelegate table(opts \\ [], blocks), to: Harmonium.Table

defdelegate table_head(opts \\ [], blocks), to: Harmonium.Table

defdelegate table_body(opts \\ [], blocks), to: Harmonium.Table

defdelegate table_row(opts \\ [], blocks), to: Harmonium.Table

defdelegate table_header(opts \\ [], blocks), to: Harmonium.Table

defdelegate table_data(opts \\ [], blocks), to: Harmonium.Table

defdelegate pagination(conn, url, page_number, total_pages), to: Harmonium.Pagination

@mock_form_default_form %Phoenix.HTML.Form{data: %{}, errors: [], name: "mock", id: "mock"}
@mock_form_default_inputs %{
empty: nil,
Expand Down
124 changes: 124 additions & 0 deletions lib/harmonium/pagination.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
defmodule Harmonium.Pagination do
@moduledoc false
@page_links_to_show 2
import Phoenix.HTML

def pagination(_conn, _url, _page_number, 1) do
nil
end

def pagination(conn, url, page_number, total_pages) do
~E"""
<div class="rev-PaginationWrapper text-center">
<ul class="rev-Pagination" role="navigation" aria-label="Pagination">
<%= unless first_page?(page_number) do %>
<li class="rev-Pagination-arrow">
<a href="<%= make_page_link(conn, 1, url) %>">
<span><i class="icon-angle-double-left"></i>First<span class="ShowForSR"> page</span></span>
</a>
</li>
<li class="rev-Pagination-arrow">
<a href="<%= make_previous_page_link(conn, page_number, url) %>">
<span><i class="icon-angle-left"></i>Previous<span class="ShowForSR"> page</span></span>
</a>
</li>
<% end %>

<%= for page <- 1..total_pages do %>
<%= if show_previous_ellipsis?(page, page_number) do %>
<li class="rev-Pagination-dots">
...
</li>
<% end %>
<%= if show_page_link?(page, page_number) do %>
<li class="rev-Pagination-number <%= selected_page_class(page, page_number)%>">
<%= if page == page_number do %>
<span class="ShowForSR">You're on page </span><a><%= page_number %></a>
<% else %>
<a href="<%= make_page_link(conn, page, url) %>" aria-label="Page <%= page %>"><%= page %></a>
<% end %>
</li>
<% end %>
<%= if show_next_ellipsis?(page, page_number, total_pages) do %>
<li class="rev-Pagination-dots">
...
</li>
<% end %>
<% end %>
<%= unless last_page?(page_number, total_pages) do %>
<li class="rev-Pagination-arrow">
<a href="<%= make_next_page_link(conn, page_number, url) %>">
<span>Next<span class="ShowForSR"> page</span><i class="icon-angle-right"></i></span>
</a>
</li>
<li class="rev-Pagination-arrow">
<a href="<%= make_page_link(conn, total_pages, url) %>">
<span>Last<span class="ShowForSR"> page</span><i class="icon-angle-double-right"></i></span>
</a>
</li>
<% end %>
</ul>
<div class="rev-PaginationWrapper-pageList">
<span class="Small">( Page <%= page_number %> of <%= total_pages %> )</span>
</div>
</div>
"""
end

defp make_next_page_link(conn, current_page, url) do
make_page_link(conn, current_page + 1, url)
end

defp make_previous_page_link(conn, current_page, url) do
make_page_link(conn, current_page - 1, url)
end

defp make_page_link(conn, page, url) do
query_params = conn.query_params

query_params = Map.put(query_params, "page", page)

uri = URI.parse(url)

query_params =
if is_nil(uri.query) do
query_params
else
URI.decode_query(uri.query, query_params)
end

uri = %{uri | query: Plug.Conn.Query.encode(query_params)}

URI.to_string(uri)
end

defp first_page?(1), do: true
defp first_page?(_), do: false

defp last_page?(page_number, total_pages) when page_number == total_pages, do: true
defp last_page?(_, _), do: false

defp selected_page_class(page_number, current_page) when page_number == current_page do
"rev-Pagination-number--selected"
end

defp selected_page_class(_, _) do
""
end

defp show_previous_ellipsis?(1, _) do
false
end

defp show_previous_ellipsis?(page, page_number) do
page == page_number - @page_links_to_show
end

defp show_next_ellipsis?(page, page_number, total_pages) do
page == page_number + @page_links_to_show and page != total_pages
end

defp show_page_link?(page, page_number) do
page >= page_number - @page_links_to_show and page <= page_number + @page_links_to_show
end
end
37 changes: 37 additions & 0 deletions lib/harmonium/table.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defmodule Harmonium.Table do
@moduledoc false

import Phoenix.HTML.Tag

def table(opts \\ [], do: block) do
table_element(:table, [class: "rev-Table"], opts, do: block)
Copy link
Contributor

@brianberlin brianberlin Apr 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change all of these to...

def table_data(opts \\ []) do
    {block, opts} = Keyword.pop(opts, :do, nil)
    table_element(:td, [class: "rev-Table"], opts, do: block)
end

Then we can do something like...

<%= table_data colspan: 5 %>
<%= table_data do: sum %>

otherwise you have to do

<%= table_data colspan: 5 do %>
  <%= sum %>
<% end %>

or you can also do this i guess but be nice to the other way i think

table_data([colspan: 5], [do: nil])

end

def table_head(opts \\ [], do: block) do
table_element(:thead, [class: "rev-Table-head"], opts, do: block)
end

def table_body(opts \\ [], do: block) do
table_element(:tbody, [class: "rev-Table-body"], opts, do: block)
end

def table_row(opts \\ [], do: block) do
table_element(:tr, [class: "rev-Table-row"], opts, do: block)
end

def table_header(opts \\ [], do: block) do
table_element(:th, [class: "rev-Table-header"], opts, do: block)
end

def table_data(opts \\ [], do: block) do
table_element(:td, [class: "rev-Table-Data"], opts, do: block)
end

defp table_element(tag, default_opts, opts, do: block) do
opts = Keyword.merge(default_opts, opts)

content_tag tag, opts do
block
end
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have said this before, but I think all these helper functions should follow the current standard Harmonium pattern where you can optionally pass CSS class modifiers as the 2nd arg:

  @doc """
  Constructs a callout class.
  """
  def callout_class(modifiers \\ []), do: rev_class(@callout_class, modifiers)

  @doc """
  Renders a callout.
  """
  def callout(do: block), do: callout([], do: block)

  def callout(modifiers, do: block), do: callout(:div, modifiers, do: block)

  def callout(tag, modifiers, do: block) do
    content_tag tag, class: callout_class(modifiers) do
      block
    end
  end

Our Harmonium SCSS Table does include some very useful SUIT modifiers: https://github.com/revelrylabs/harmonium/blob/master/scss/components/_Table.scss

2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%{
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.7.0", "30d6b52c88541f9a66637359ddf85016df9eb266170d53105f02e4a67e00c5aa", [], [], "hexpm"},
"decimal": {:hex, :decimal, "1.7.0", "30d6b52c88541f9a66637359ddf85016df9eb266170d53105f02e4a67e00c5aa", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.20.0", "47ef7d09d990fa4a4373c96c4bdff846836f011e88dd7695d31f54ec035ff38e", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
Expand Down