Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Override table heading attrs #265

Merged
merged 7 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading