defmodule DaisyUIComponents.Table do
@moduledoc """
Table component
https://daisyui.com/components/table/
"""
use DaisyUIComponents.Component
@doc ~S"""
Renders a table with generic styling.
## Examples
<.table id="users" rows={@users}>
<:col :let={user} label="id"><%= user.id %>
<:col :let={user} label="username"><%= user.username %>
or declaring the table components
<.table id="users">
<.thead>
<.tr>
<.th>id
<.th>username
<.tbody>
<.tr :for={user <- @users}>
<.td><%= user.id %>
<.td><%= user.username %>
"""
attr :id, :string, default: nil
attr :rows, :list
attr :row_id, :any, default: nil, doc: "the function for generating the row id"
attr :row_click, :any, default: nil, doc: "the function for handling phx-click on each row"
attr :row_item, :any,
default: &Function.identity/1,
doc: "the function for mapping each row before calling the :col and :action slots"
slot :col do
attr :label, :string
end
slot :action, doc: "the slot for showing user actions in the last table column"
attr :zebra, :boolean, default: false
attr :size, :string, values: sizes()
attr :rest, :global
slot :inner_block
def table(%{rows: _rows} = assigns) do
assigns =
join_classes_with_rest(assigns, [
"table",
add_class_from_bool(assigns[:zebra], "table-zebra"),
table_size(assigns[:size])
])
assigns =
with %{rows: %Phoenix.LiveView.LiveStream{}} <- assigns do
assign(assigns, row_id: assigns.row_id || fn {id, _item} -> id end)
end
~H"""
<.thead>
<.tr>
<.th :for={col <- @col}><%= col[:label] %>
<.th :if={@action != []}>
<%= translate("Actions") %>
<.tbody id={@id} phx-update={match?(%Phoenix.LiveView.LiveStream{}, @rows) && "stream"}>
<.tr :for={row <- @rows} id={@row_id && @row_id.(row)}>
<.td
:for={col <- @col}
phx-click={@row_click && @row_click.(row)}
class={[@row_click && "hover:cursor-pointer"]}
>
<%= render_slot(col, @row_item.(row)) %>
<.td :if={@action != []}>
<%= render_slot(action, @row_item.(row)) %>
"""
end
def table(assigns) do
assigns =
join_classes_with_rest(assigns, [
"table",
add_class_from_bool(assigns[:zebra], "table-zebra"),
table_size(assigns[:size])
])
~H"""
<%= render_slot(@inner_block) %>
"""
end
attr :active, :boolean, default: false
attr :hover, :boolean, default: false
attr :rest, :global
slot :inner_block
def tr(assigns) do
assigns =
join_classes_with_rest(assigns, [
add_class_from_bool(assigns[:active], "active"),
add_class_from_bool(assigns[:hover], "hover")
])
~H"""
<%= render_slot(@inner_block) %>
"""
end
attr :rest, :global
slot :inner_block
def td(assigns) do
~H"""
<%= render_slot(@inner_block) %>
|
"""
end
attr :rest, :global
slot :inner_block
def th(assigns) do
~H"""
<%= render_slot(@inner_block) %>
|
"""
end
attr :rest, :global
slot :inner_block
def thead(assigns) do
~H"""
<%= render_slot(@inner_block) %>
"""
end
attr :rest, :global
slot :inner_block
def tbody(assigns) do
~H"""
<%= render_slot(@inner_block) %>
"""
end
# Size
defp table_size("xs"), do: "table-xs"
defp table_size("sm"), do: "table-sm"
defp table_size("md"), do: "table-md"
defp table_size("lg"), do: "table-lg"
defp table_size(_size), do: nil
end