diff --git a/lib/phoenix_better_table.ex b/lib/phoenix_better_table.ex index 657fa0d..638a4ae 100644 --- a/lib/phoenix_better_table.ex +++ b/lib/phoenix_better_table.ex @@ -21,6 +21,7 @@ defmodule PhoenixBetterTable do * `:filter_control` - an optional slot that takes a single argument, a tuple of `{active?, id, myself}`. The interactive element should set `phx-click="filter_toggle"`, `phx-value-header={id}`, and `phx-target={myself}` for the event to be routed correctly. + * `:sort_control` - an optional slot that takes a single argument, a tuple of `{direction, id, myself}`. See above. """ use Phoenix.LiveComponent @@ -91,6 +92,7 @@ defmodule PhoenixBetterTable do |> assign_new(:engine_module, fn -> engine_module() end) |> assign_new(:sort, fn -> nil end) |> assign_new(:filter, fn -> %{} end) + |> assign_new(:sort_control, fn -> nil end) |> assign_new(:filter_control, fn -> nil end) |> assign_new(:class, fn -> "" end) |> assign_new(:body_class, fn -> "" end) @@ -154,10 +156,23 @@ defmodule PhoenixBetterTable do defp column_filter(_), do: &to_string/1 - defp sort_arrow(nil, _column), do: "—" - defp sort_arrow({column, order}, column) when order == :asc, do: "▲" - defp sort_arrow({column, order}, column) when order == :desc, do: "▼" - defp sort_arrow(_, _), do: "—" + defp column_sort_order({column, order}, column), do: order + defp column_sort_order(_, _), do: nil + + attr(:direction, :atom, required: true) + attr(:rest, :global) + + defp sort_control(assigns) do + ~H""" + + <%= case @direction do + nil -> "—" + :asc -> "▲" + :desc -> "▼" + end %> + + """ + end attr(:active?, :boolean, required: true) attr(:rest, :global) diff --git a/lib/phoenix_better_table.html.heex b/lib/phoenix_better_table.html.heex index 53d7935..d416759 100644 --- a/lib/phoenix_better_table.html.heex +++ b/lib/phoenix_better_table.html.heex @@ -3,9 +3,13 @@ <%= Map.get(header, :label, header.id) %> - - <%= sort_arrow(@sort, header.id) %> - + <%= if Map.get(header, :sort, true) do %> + <%= if @sort_control do %> + <%= render_slot(@sort_control, {column_sort_order(@sort, header.id), header.id, @myself}) %> + <% else %> + <.sort_control direction={column_sort_order(@sort, header.id)} phx-click="sort" phx-value-header={header.id} phx-target={@myself} /> + <% end %> + <% end %>   <%= if @filter_control do %> <%= render_slot(@filter_control, {Map.has_key?(@filter, header.id), header.id, @myself}) %> diff --git a/test/phoenix_better_table_test.exs b/test/phoenix_better_table_test.exs index 6d9017b..6668334 100644 --- a/test/phoenix_better_table_test.exs +++ b/test/phoenix_better_table_test.exs @@ -287,6 +287,30 @@ defmodule PhoenixBetterTableTest do """) end + test "custom sort control can be passed as slot" do + {:ok, view, _html} = + live_isolated_component(PhoenixBetterTable, + assigns: %{ + meta: %{headers: [%{id: :name}]}, + rows: [%{name: "John"}, %{name: "Jane"}] + }, + slots: %{ + sort_control: + slot(let: {direction, id, myself}) do + ~H[Sort (<%= direction %>)] + end + } + ) + + html = view |> element("span[phx-click='sort']") |> render_click() + + assert_table_matches(html, """ + name + Jane + John + """) + end + test "custom filter control can be passed as a slot" do {:ok, view, _html} = live_isolated_component(PhoenixBetterTable,