Skip to content

Commit

Permalink
feat: Add table.
Browse files Browse the repository at this point in the history
  • Loading branch information
GSMLG-BOT committed Apr 29, 2022
1 parent 44f40b1 commit 62ff8f7
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 23 deletions.
1 change: 1 addition & 0 deletions lib/phoenix_webcomponent.ex
Expand Up @@ -30,6 +30,7 @@ defmodule Phoenix.WebComponent do
import Phoenix.WebComponent.Link
import Phoenix.WebComponent.Markdown
import Phoenix.WebComponent.TopAppBar
import Phoenix.WebComponent.Table
end
end

Expand Down
8 changes: 4 additions & 4 deletions lib/phoenix_webcomponent/link.ex
Expand Up @@ -83,7 +83,7 @@ defmodule Phoenix.WebComponent.Link do
{linkOpts, opts} = pop_link_attr(Keyword.delete(opts, :csrf_token))

content_tag(:a, [href: data[:to]] ++ linkOpts) do
content_tag(:"bx-btn", text, opts)
content_tag(:"bx-link", text, opts)
end
else
{csrf_token, opts} = Keyword.pop(opts, :csrf_token, true)
Expand All @@ -95,7 +95,7 @@ defmodule Phoenix.WebComponent.Link do
{linkOpts, opts} = pop_link_attr(opts)

content_tag(:a, [data: data, href: data[:to]] ++ linkOpts) do
content_tag(:"bx-btn", text, opts)
content_tag(:"bx-link", text, opts)
end
end
end
Expand Down Expand Up @@ -149,7 +149,7 @@ defmodule Phoenix.WebComponent.Link do
|> Keyword.split([:method, :csrf_token])

link_attributes = Phoenix.WebComponent.link_attributes(to, link_opts)
content_tag(:"bx-btn", text, link_attributes ++ opts)
content_tag(:"bx-link", text, link_attributes ++ opts)
end

defp pop_required_option!(opts, key, error_message) do
Expand Down Expand Up @@ -290,7 +290,7 @@ defmodule Phoenix.WebComponent.Link do
{linkOpts, opts} = pop_link_attr(opts)

content_tag(:a, linkOpts) do
content_tag(:"bx-btn", opts, do: block_or_text)
content_tag(:"bx-link", opts, do: block_or_text)
end
end
end
96 changes: 96 additions & 0 deletions lib/phoenix_webcomponent/table.ex
@@ -0,0 +1,96 @@
defmodule Phoenix.WebComponent.Table do
@moduledoc """
Render a data table.
The table is bx-table custom element.
"""

import Phoenix.HTML.Tag

@doc """
Generates a html customElement bx-data-table.
Docs of bx-data-table (See https://web-components.carbondesignsystem.com/?path=/story/components-data-table--default).
## Examples
wc_table([%{name: "Jonathan"}], [columns: [name: "Name"]])
#=> <bx-data-table>
#=> <bx-table>
#=> <bx-table-head>
#=> <bx-table-header-row>
#=> <bx-table-header-cell>Name</bx-table-header-cell>
#=> </bx-table-header-row>
#=> </bx-table-head>
#=> <bx-table-body>
#=> <bx-table-row>
#=> <bx-table-cell>Jonathan</bx-table-cell>
#=> </bx-table-row>
#=> </bx-table-body>
#=> </bx-table>
#=> </bx-data-table>
## Options
* `:columns` - print log in browser console
* `:content_columns` - columns that have special renderer.
* `:content_functions` - renderer defined in `:content_columns`
* `:toolbar_actions` - Action buttons at top right.
All other options are forwarded to the underlying button input.
"""
def wc_table(data, opts) do
{toolbar_actions, opts} = Keyword.pop(opts, :toolbar_actions, [])

{columns, opts} = Keyword.pop(opts, :columns, [])
{content_columns, opts} = Keyword.pop(opts, :content_columns, [])
{content_functions, opts} = Keyword.pop(opts, :content_functions, [])

content_tag(:"bx-data-table", opts) do
[
content_tag(:"bx-table-toolbar", []) do
[
content_tag(:"bx-table-batch-actions", []) do
end,
content_tag(:"bx-table-toolbar-content", []) do
toolbar_actions
end
]
end,
content_tag(:"bx-table", []) do
[
content_tag(:"bx-table-head", []) do
content_tag(:"bx-table-header-row", []) do
Enum.map(columns, fn {_, v} ->
content_tag(:"bx-table-header-cell", v, "sort-active": true)
end)
end
end,
content_tag(:"bx-table-body", []) do
Enum.map(data, fn d ->
content_tag(:"bx-table-row", []) do
Enum.map(columns, fn {k, _} ->
if k in content_columns do
content_tag(:"bx-table-cell", []) do
idx = Enum.find_index(content_columns, fn n -> n == k end)
func = Enum.at(content_functions, idx, fn d -> Map.get(d, k) end)
func.(d)
end
else
content_tag(:"bx-table-cell", Map.get(d, k), [])
end
end)
end
end)
end
]
end
]
end
end
end
38 changes: 19 additions & 19 deletions test/phoenix_webcomponent/link_test.exs
Expand Up @@ -8,7 +8,7 @@ defmodule Phoenix.WebComponent.LinkTest do
csrf_token = Plug.CSRFProtection.get_csrf_token()

assert safe_to_string(wc_link("hello", to: "/world", method: :post)) ==
~s[<a data-csrf="#{csrf_token}" data-method="post" data-to="/world" href="/world" rel="nofollow"><bx-btn>hello</bx-btn></a>]
~s[<a data-csrf="#{csrf_token}" data-method="post" data-to="/world" href="/world" rel="nofollow"><bx-link>hello</bx-link></a>]
end

test "wc_link with %URI{}" do
Expand All @@ -27,16 +27,16 @@ defmodule Phoenix.WebComponent.LinkTest do
csrf_token = Plug.CSRFProtection.get_csrf_token()

assert safe_to_string(wc_link("hello", to: "/world", method: :put)) ==
~s[<a data-csrf="#{csrf_token}" data-method="put" data-to="/world" href="/world" rel="nofollow"><bx-btn>hello</bx-btn></a>]
~s[<a data-csrf="#{csrf_token}" data-method="put" data-to="/world" href="/world" rel="nofollow"><bx-link>hello</bx-link></a>]
end

test "wc_link with put/delete without csrf_token" do
assert safe_to_string(wc_link("hello", to: "/world", method: :put, csrf_token: false)) ==
~s[<a data-method="put" data-to="/world" href="/world" rel="nofollow"><bx-btn>hello</bx-btn></a>]
~s[<a data-method="put" data-to="/world" href="/world" rel="nofollow"><bx-link>hello</bx-link></a>]
end

test "wc_link with :do contents" do
assert ~s[<a href="/hello"><bx-btn><p>world</p></bx-btn></a>] ==
assert ~s[<a href="/hello"><bx-link><p>world</p></bx-link></a>] ==
safe_to_string(
wc_link to: "/hello" do
Phoenix.HTML.Tag.content_tag(:p, "world")
Expand All @@ -47,27 +47,27 @@ defmodule Phoenix.WebComponent.LinkTest do
wc_link(to: "/hello") do
"world"
end
) == ~s[<a href="/hello"><bx-btn>world</bx-btn></a>]
) == ~s[<a href="/hello"><bx-link>world</bx-link></a>]
end

test "wc_link with scheme" do
assert safe_to_string(wc_link("foo", to: "/javascript:alert(<1>)")) ==
~s[<a href="/javascript:alert(&lt;1&gt;)"><bx-btn>foo</bx-btn></a>]
~s[<a href="/javascript:alert(&lt;1&gt;)"><bx-link>foo</bx-link></a>]

assert safe_to_string(wc_link("foo", to: {:safe, "/javascript:alert(<1>)"})) ==
~s[<a href="/javascript:alert(<1>)"><bx-btn>foo</bx-btn></a>]
~s[<a href="/javascript:alert(<1>)"><bx-link>foo</bx-link></a>]

assert safe_to_string(wc_link("foo", to: {:javascript, "alert(<1>)"})) ==
~s[<a href="javascript:alert(&lt;1&gt;)"><bx-btn>foo</bx-btn></a>]
~s[<a href="javascript:alert(&lt;1&gt;)"><bx-link>foo</bx-link></a>]

assert safe_to_string(wc_link("foo", to: {:javascript, 'alert(<1>)'})) ==
~s[<a href="javascript:alert(&lt;1&gt;)"><bx-btn>foo</bx-btn></a>]
~s[<a href="javascript:alert(&lt;1&gt;)"><bx-link>foo</bx-link></a>]

assert safe_to_string(wc_link("foo", to: {:javascript, {:safe, "alert(<1>)"}})) ==
~s[<a href="javascript:alert(<1>)"><bx-btn>foo</bx-btn></a>]
~s[<a href="javascript:alert(<1>)"><bx-link>foo</bx-link></a>]

assert safe_to_string(wc_link("foo", to: {:javascript, {:safe, 'alert(<1>)'}})) ==
~s[<a href="javascript:alert(<1>)"><bx-btn>foo</bx-btn></a>]
~s[<a href="javascript:alert(<1>)"><bx-link>foo</bx-link></a>]
end

test "wc_link with confirm" do
Expand All @@ -76,7 +76,7 @@ defmodule Phoenix.WebComponent.LinkTest do
assert safe_to_string(
wc_link("hello", to: "/world", method: :delete, data: [confirm: "Are you sure?"])
) ==
~s[<a data-confirm="Are you sure?" data-csrf="#{csrf_token}" data-method="delete" data-to="/world" href="/world" rel="nofollow"><bx-btn>hello</bx-btn></a>]
~s[<a data-confirm="Are you sure?" data-csrf="#{csrf_token}" data-method="delete" data-to="/world" href="/world" rel="nofollow"><bx-link>hello</bx-link></a>]
end

test "wc_link with invalid args" do
Expand Down Expand Up @@ -109,7 +109,7 @@ defmodule Phoenix.WebComponent.LinkTest do
csrf_token = Plug.CSRFProtection.get_csrf_token()

assert safe_to_string(wc_button("hello", to: "/world")) ==
~s[<bx-btn data-csrf="#{csrf_token}" data-method="post" data-to="/world">hello</bx-btn>]
~s[<bx-link data-csrf="#{csrf_token}" data-method="post" data-to="/world">hello</bx-link>]
end

test "wc_button with %URI{}" do
Expand All @@ -121,12 +121,12 @@ defmodule Phoenix.WebComponent.LinkTest do

test "wc_button with post without csrf_token" do
assert safe_to_string(wc_button("hello", to: "/world", csrf_token: false)) ==
~s[<bx-btn data-method="post" data-to="/world">hello</bx-btn>]
~s[<bx-link data-method="post" data-to="/world">hello</bx-link>]
end

test "wc_button with get does not generate CSRF" do
assert safe_to_string(wc_button("hello", to: "/world", method: :get)) ==
~s[<bx-btn data-method="get" data-to="/world">hello</bx-btn>]
~s[<bx-link data-method="get" data-to="/world">hello</bx-link>]
end

test "wc_button with do" do
Expand All @@ -140,14 +140,14 @@ defmodule Phoenix.WebComponent.LinkTest do
)

assert output ==
~s[<bx-btn class="small" data-csrf="#{csrf_token}" data-method="post" data-to="/world"><span>Hi</span></bx-btn>]
~s[<bx-link class="small" data-csrf="#{csrf_token}" data-method="post" data-to="/world"><span>Hi</span></bx-link>]
end

test "wc_button with class overrides default" do
csrf_token = Plug.CSRFProtection.get_csrf_token()

assert safe_to_string(wc_button("hello", to: "/world", class: "btn rounded", id: "btn")) ==
~s[<bx-btn class="btn rounded" data-csrf="#{csrf_token}" data-method="post" data-to="/world" id="btn">hello</bx-btn>]
~s[<bx-link class="btn rounded" data-csrf="#{csrf_token}" data-method="post" data-to="/world" id="btn">hello</bx-link>]
end

test "wc_button with invalid args" do
Expand All @@ -159,12 +159,12 @@ defmodule Phoenix.WebComponent.LinkTest do
describe "live view link" do
test "wc_live_patch" do
assert safe_to_string(wc_live_patch("hello", to: "/world")) ==
~s[<a data-phx-link="patch" data-phx-link-state="push" href="/world"><bx-btn>hello</bx-btn></a>]
~s[<a data-phx-link="patch" data-phx-link-state="push" href="/world"><bx-link>hello</bx-link></a>]
end

test "wc_live_redirect" do
assert safe_to_string(wc_live_redirect("hello", to: "/world")) ==
~s[<a data-phx-link="redirect" data-phx-link-state="push" href="/world"><bx-btn>hello</bx-btn></a>]
~s[<a data-phx-link="redirect" data-phx-link-state="push" href="/world"><bx-link>hello</bx-link></a>]
end
end
end
11 changes: 11 additions & 0 deletions test/phoenix_webcomponent/table_test.exs
@@ -0,0 +1,11 @@
defmodule Phoenix.WebComponent.TableTest do
use ExUnit.Case, async: true

import Phoenix.HTML
import Phoenix.WebComponent.Table

test "wc-table" do
assert safe_to_string(wc_table([%{name: "Jonathan"}], columns: [name: "Name"])) ==
~s[<bx-data-table><bx-table-toolbar><bx-table-batch-actions></bx-table-batch-actions><bx-table-toolbar-content></bx-table-toolbar-content></bx-table-toolbar><bx-table><bx-table-head><bx-table-header-row><bx-table-header-cell sort-active>Name</bx-table-header-cell></bx-table-header-row></bx-table-head><bx-table-body><bx-table-row><bx-table-cell>Jonathan</bx-table-cell></bx-table-row></bx-table-body></bx-table></bx-data-table>]
end
end

0 comments on commit 62ff8f7

Please sign in to comment.