Skip to content

Commit

Permalink
Merge pull request #265 from dsrees/override-table-heading-attrs
Browse files Browse the repository at this point in the history
Override table heading attrs
  • Loading branch information
woylie authored Sep 26, 2023
2 parents df23478 + 7a17a18 commit bef307e
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 17 deletions.
24 changes: 22 additions & 2 deletions lib/flop_phoenix.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,22 @@ defmodule Flop.Phoenix do
of a column this way.
"""

attr :attrs, :any,
attr :thead_th_attrs, :list,
doc: """
Additional attributes to pass to the `<th>` element as a static keyword
list. Note that these attributes will override any conflicting
`thead_th_attrs` that are set at the table level.
"""

attr :th_wrapper_attrs, :list,
doc: """
Additional attributes for the `<span>` element that wraps the
header link and the order direction symbol. Note that these attributes
will override any conflicting `th_wrapper_attrs` that are set at the table
level.
"""

attr :tbody_td_attrs, :any,
doc: """
Additional attributes to pass to the `<td>` element. May be provided as a
static keyword list, or as a 1-arity function to dynamically generate the
Expand Down Expand Up @@ -1083,7 +1098,12 @@ defmodule Flop.Phoenix do
of a column this way.
"""

attr :attrs, :any,
attr :thead_th_attrs, :list,
doc: """
Any additional attributes to pass to the `<th>` as a keyword list.
"""

attr :tbody_td_attrs, :any,
doc: """
Any additional attributes to pass to the `<td>`. Can be a keyword list or
a function that takes the current row item as an argument and returns a
Expand Down
21 changes: 17 additions & 4 deletions lib/flop_phoenix/table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,16 @@ defmodule Flop.Phoenix.Table do
label={col[:label]}
sortable={sortable?(col[:field], @meta.schema)}
meta={@meta}
thead_th_attrs={@opts[:thead_th_attrs]}
thead_th_attrs={
merge_attrs(@opts[:thead_th_attrs], col, :thead_th_attrs)
}
symbol_asc={@opts[:symbol_asc]}
symbol_desc={@opts[:symbol_desc]}
symbol_unsorted={@opts[:symbol_unsorted]}
symbol_attrs={@opts[:symbol_attrs]}
th_wrapper_attrs={@opts[:th_wrapper_attrs]}
th_wrapper_attrs={
merge_attrs(@opts[:th_wrapper_attrs], col, :th_wrapper_attrs)
}
path={@path}
target={@target}
/>
Expand All @@ -99,7 +103,9 @@ defmodule Flop.Phoenix.Table do
label={action[:label]}
sortable={false}
meta={@meta}
thead_th_attrs={@opts[:thead_th_attrs]}
thead_th_attrs={
merge_attrs(@opts[:thead_th_attrs], action, :thead_th_attrs)
}
path={nil}
target={@event}
/>
Expand Down Expand Up @@ -136,8 +142,15 @@ defmodule Flop.Phoenix.Table do
"""
end

defp merge_attrs(base_attrs, col, key) when is_atom(key) do
attrs = Map.get(col, key, [])
Keyword.merge(base_attrs, attrs)
end

defp merge_td_attrs(tbody_td_attrs, col, item) do
attrs = col |> Map.get(:attrs, []) |> maybe_invoke_options_callback(item)
attrs =
col |> Map.get(:tbody_td_attrs, []) |> maybe_invoke_options_callback(item)

Keyword.merge(tbody_td_attrs, attrs)
end

Expand Down
145 changes: 134 additions & 11 deletions test/flop_phoenix_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1782,7 +1782,7 @@ defmodule Flop.PhoenixTest do
assert [_] = Floki.find(html, "tr.crime-reporter")
end

test "evaluates attrs function for col slot / td" do
test "evaluates tbody_td_attrs function for col slot / td" do
assigns = %{}

html =
Expand All @@ -1795,7 +1795,7 @@ defmodule Flop.PhoenixTest do
]}
meta={%Flop.Meta{flop: %Flop{}}}
>
<:col attrs={
<:col tbody_td_attrs={
fn item ->
[class: if(item.age > 17, do: "adult", else: "child")]
end
Expand All @@ -1808,7 +1808,7 @@ defmodule Flop.PhoenixTest do
assert [_] = Floki.find(html, "td.child")
end

test "evaluates attrs function in action columns" do
test "evaluates tbody_td_attrs function in action columns" do
assigns = %{
attrs_fun: fn item ->
[class: if(item.age > 17, do: "adult", else: "child")]
Expand All @@ -1826,7 +1826,7 @@ defmodule Flop.PhoenixTest do
on_sort={%JS{}}
>
<:col :let={u} label="Name"><%= u.name %></:col>
<:action label="Buttons" attrs={@attrs_fun}>some action</:action>
<:action label="Buttons" tbody_td_attrs={@attrs_fun}>some action</:action>
</Flop.Phoenix.table>
""")

Expand All @@ -1853,6 +1853,33 @@ defmodule Flop.PhoenixTest do
assert [_, _] = Floki.find(html, "td.tolerance")
end

test "adds additional attributes to th" do
assigns = %{}

html =
parse_heex(~H"""
<Flop.Phoenix.table
path="/pets"
items={[%{name: "George", age: 8}]}
meta={%Flop.Meta{flop: %Flop{}}}
>
<:col :let={pet} thead_th_attrs={[class: "name-header"]}>
<%= pet.name %>
</:col>
<:col :let={pet} thead_th_attrs={[class: "age-header"]}>
<%= pet.age %>
</:col>
<:action :let={pet} thead_th_attrs={[class: "action-header"]}>
<.link navigate={"/show/pet/#{pet.name}"}>Show Pet</.link>
</:action>
</Flop.Phoenix.table>
""")

assert [_] = Floki.find(html, "th.name-header")
assert [_] = Floki.find(html, "th.age-header")
assert [_] = Floki.find(html, "th.action-header")
end

test "adds additional attributes to td" do
assigns = %{}

Expand All @@ -1863,13 +1890,13 @@ defmodule Flop.PhoenixTest do
items={[%{name: "George", age: 8}]}
meta={%Flop.Meta{flop: %Flop{}}}
>
<:col :let={pet} attrs={[class: "name-column"]}>
<:col :let={pet} tbody_td_attrs={[class: "name-column"]}>
<%= pet.name %>
</:col>
<:col :let={pet} attrs={[class: "age-column"]}>
<:col :let={pet} tbody_td_attrs={[class: "age-column"]}>
<%= pet.age %>
</:col>
<:action :let={pet} attrs={[class: "action-column"]}>
<:action :let={pet} tbody_td_attrs={[class: "action-column"]}>
<.link navigate={"/show/pet/#{pet.name}"}>Show Pet</.link>
</:action>
</Flop.Phoenix.table>
Expand All @@ -1880,7 +1907,80 @@ defmodule Flop.PhoenixTest do
assert [_] = Floki.find(html, "td.action-column")
end

test "overrides table_td_attrs with td attrs" do
test "overrides table_th_attrs with thead_th_attrs in col" do
assigns = %{
meta: %Flop.Meta{flop: %Flop{}, schema: MyApp.Pet},
items: [%{name: "George", age: 8}],
opts: [thead_th_attrs: [class: "default-th-class"]]
}

html =
parse_heex(~H"""
<Flop.Phoenix.table items={@items} meta={@meta} on_sort={%JS{}} opts={@opts}>
<:col :let={i} thead_th_attrs={[class: "name-th-class"]}><%= i.name %></:col>
<:col :let={i}><%= i.age %></:col>
</Flop.Phoenix.table>
""")

assert [{"th", [{"class", "name-th-class"}], _}] =
Floki.find(html, "th:first-child")

assert [{"th", [{"class", "default-th-class"}], _}] =
Floki.find(html, "th:last-child")
end

test "evaluates table th_wrapper_attrs" do
assigns = %{
meta: %Flop.Meta{flop: %Flop{}, schema: MyApp.Pet},
items: [%{name: "George", age: 8}],
opts: [th_wrapper_attrs: [class: "default-th-wrapper-class"]]
}

html =
parse_heex(~H"""
<Flop.Phoenix.table items={@items} meta={@meta} on_sort={%JS{}} opts={@opts}>
<:col :let={i} field={:name}><%= i.name %></:col>
<:col :let={i}><%= i.age %></:col>
</Flop.Phoenix.table>
""")

assert [
{"th", [],
[{"span", [{"class", "default-th-wrapper-class"}], _}]}
] = Floki.find(html, "th:first-child")
end

test "overrides th_wrapper_attrs" do
assigns = %{
meta: %Flop.Meta{flop: %Flop{}, schema: MyApp.Pet},
items: [%{name: "George", age: 8}],
opts: [th_wrapper_attrs: [class: "default-th-wrapper-class"]]
}

html =
parse_heex(~H"""
<Flop.Phoenix.table items={@items} meta={@meta} on_sort={%JS{}} opts={@opts}>
<:col
:let={i}
field={:name}
th_wrapper_attrs={[class: "name-th-wrapper-class"]}
>
<%= i.name %>
</:col>
<:col :let={i} field={:age}><%= i.age %></:col>
</Flop.Phoenix.table>
""")

assert [{"th", [], [{"span", [{"class", "name-th-wrapper-class"}], _}]}] =
Floki.find(html, "th:first-child")

assert [
{"th", [],
[{"span", [{"class", "default-th-wrapper-class"}], _}]}
] = Floki.find(html, "th:last-child")
end

test "overrides table_td_attrs with tbody_td_attrs in col" do
assigns = %{
meta: %Flop.Meta{flop: %Flop{}, schema: MyApp.Pet},
items: [%{name: "George", age: 8}],
Expand All @@ -1890,7 +1990,7 @@ defmodule Flop.PhoenixTest do
html =
parse_heex(~H"""
<Flop.Phoenix.table items={@items} meta={@meta} on_sort={%JS{}} opts={@opts}>
<:col :let={i} attrs={[class: "name-td-class"]}><%= i.name %></:col>
<:col :let={i} tbody_td_attrs={[class: "name-td-class"]}><%= i.name %></:col>
<:col :let={i}><%= i.age %></:col>
</Flop.Phoenix.table>
""")
Expand All @@ -1902,7 +2002,30 @@ defmodule Flop.PhoenixTest do
Floki.find(html, "td:last-child")
end

test "overrides table_td_attrs with td attrs in action columns" do
test "overrides table_th_attrs with thead_th_attrs in action columns" do
assigns = %{
meta: %Flop.Meta{flop: %Flop{}, schema: MyApp.Pet},
items: [%{name: "George", age: 8}],
opts: [thead_th_attrs: [class: "default-th-class"]]
}

html =
parse_heex(~H"""
<Flop.Phoenix.table items={@items} meta={@meta} on_sort={%JS{}} opts={@opts}>
<:col :let={i}><%= i.name %></:col>
<:action thead_th_attrs={[class: "action-1-th-class"]}>action 1</:action>
<:action>action 2</:action>
</Flop.Phoenix.table>
""")

assert [{"th", [{"class", "action-1-th-class"}], _}] =
Floki.find(html, "th:nth-child(2)")

assert [{"th", [{"class", "default-th-class"}], _}] =
Floki.find(html, "th:last-child")
end

test "overrides table_td_attrs with tbody_td_attrs in action columns" do
assigns = %{
meta: %Flop.Meta{flop: %Flop{}, schema: MyApp.Pet},
items: [%{name: "George", age: 8}],
Expand All @@ -1913,7 +2036,7 @@ defmodule Flop.PhoenixTest do
parse_heex(~H"""
<Flop.Phoenix.table items={@items} meta={@meta} on_sort={%JS{}} opts={@opts}>
<:col :let={i}><%= i.name %></:col>
<:action attrs={[class: "action-1-td-class"]}>action 1</:action>
<:action tbody_td_attrs={[class: "action-1-td-class"]}>action 1</:action>
<:action>action 2</:action>
</Flop.Phoenix.table>
""")
Expand Down

0 comments on commit bef307e

Please sign in to comment.