diff --git a/lib/doggo.ex b/lib/doggo.ex
index dab8ef8e..d4e8f5f2 100644
--- a/lib/doggo.ex
+++ b/lib/doggo.ex
@@ -1823,6 +1823,151 @@ defmodule Doggo do
"""
end
+ @doc """
+ Renders a simple table.
+
+ ## Examples
+
+ <.table id="pets" rows={@pets}>
+ <:col :let={p} label="name"><%= p.name %>
+ <:col :let={p} label="age"><%= p.age %>
+
+ """
+ attr :id, :string, required: true
+
+ attr :items, :list,
+ required: true,
+ doc: "The list of items to be displayed in rows."
+
+ attr :caption, :string,
+ default: nil,
+ doc: "Content for the `
` element."
+
+ attr :row_id, :any,
+ default: nil,
+ doc: """
+ Overrides the default function that retrieves the row ID from a stream item.
+ """
+
+ attr :row_click, JS,
+ default: nil,
+ doc: """
+ Sets the `phx-click` function attribute for each row `td`. Expects to be a
+ function that receives a row item as an argument. This does not add the
+ `phx-click` attribute to the `action` slot.
+
+ Example:
+
+ ```elixir
+ row_click={&JS.navigate(~p"/users/\#{&1}")}
+ ```
+ """
+
+ attr :row_item, :any,
+ default: &Function.identity/1,
+ doc: """
+ This function is called on the row item before it is passed to the :col
+ and :action slots.
+ """
+
+ slot :col,
+ required: true,
+ doc: """
+ For each column to render, add one `<:col>` element.
+
+ ```elixir
+ <:col :let={pet} label="Name" field={:name} col_style="width: 20%;">
+ <%= pet.name %>
+
+ ```
+
+ Any additional assigns will be added as attributes to the `` elements.
+
+ """ do
+ attr :label, :any, doc: "The content for the header column."
+
+ attr :col_attrs, :string,
+ doc: """
+ If set, a `` element is rendered and the attributes are added
+ to the `` element of the respective column.
+ """
+ end
+
+ slot :action,
+ doc: """
+ The slot for showing user actions in the last table column. These columns
+ do not receive the `row_click` attribute.
+
+
+ ```elixir
+ <:action :let={user}>
+ <.link navigate={~p"/users/\#{user}"}>Show
+
+ ```
+ """ do
+ attr :label, :string, doc: "The content for the header column."
+
+ attr :col_attrs, :string,
+ doc: """
+ If set, a `` element is rendered and the attributes are added
+ to the `` element of the respective column.
+ """
+ end
+
+ slot :foot,
+ default: nil,
+ doc: """
+ You can optionally add a `foot`. The inner block will be rendered inside
+ a `tfoot` element.
+
+
+ <:foot>
+ Total: <%= @total %> |
+
+
+ """
+
+ def table(assigns) do
+ assigns =
+ with %{rows: %Phoenix.LiveView.LiveStream{}} <- assigns do
+ assign(assigns, row_id: assigns.row_id || fn {id, _item} -> id end)
+ end
+
+ ~H"""
+
+
+ <%= @caption %>
+
+
+
+
+
+
+ <%= col[:label] %> |
+ <%= action[:label] %> |
+
+
+ "-tbody"}
+ phx-update={match?(%Phoenix.LiveView.LiveStream{}, @rows) && "stream"}
+ >
+
+
+ <%= render_slot(col, @row_item.(row)) %>
+ |
+
+ <%= render_slot(action, @row_item.(row)) %>
+ |
+
+
+ <%= render_slot(@foot) %>
+
+
+ """
+ end
+
@doc """
Renders a drawer with a `brand`, `top`, and `bottom` slot.
|