Components
Table
Table
Tables are a great way to clearly display a collections of data grouped into columns and rows.
Dynamic table
Name | Age | |
---|---|---|
John Smith | 30 |
|
Beth Springs | 25 |
|
Peter Knowles | 40 |
|
Sarah Hill | 35 |
|
<.table
id="posts"
row_id={fn post -> "row_#{post.id}" end}
row_click={fn post -> JS.navigate(~p"/components/table#row_#{post.id}") end}
rows={[
%{
id: 1,
name: "John Smith",
age: 30
},
%{
id: 2,
name: "Beth Springs",
age: 25
},
%{
id: 3,
name: "Peter Knowles",
age: 40
},
%{
id: 4,
name: "Sarah Hill",
age: 35
}
]}
>
<:col :let={post} label="Name"><%= post.name %></:col>
<:col :let={post} label="Age"><%= post.age %></:col>
<:col class="w-64">
<div class="flex gap-2 items-center justify-end">
<.button label="Show" />
<.button label="Delete" color="danger" />
</div>
</:col>
</.table>
With streams
Basic table
Name | Title | |
---|---|---|
John Smith | Engineer | john.smith@example.com |
Beth Springs | Developer | beth.springs@example.com |
Peter Knowles | Programmer | Peter.knowles@example.com |
Sarah Hill | Marketer | sarah.hill@example.com |
<.table>
<.tr>
<.th>Name</.th>
<.th>Title</.th>
<.th>Email</.th>
</.tr>
<.tr>
<.td>
John Smith
</.td>
<.td>Engineer</.td>
<.td>john.smith@example.com</.td>
</.tr>
<.tr>
<.td>
Beth Springs
</.td>
<.td>Developer</.td>
<.td>beth.springs@example.com</.td>
</.tr>
<.tr>
<.td>
Peter Knowles
</.td>
<.td>Programmer</.td>
<.td>Peter.knowles@example.com</.td>
</.tr>
<.tr>
<.td>
Sarah Hill
</.td>
<.td>Marketer</.td>
<.td>sarah.hill@example.com</.td>
</.tr>
</.table>
Multi-lined table with avatars and badges
Name | Title | Phone | Status | |
---|---|---|---|---|
John Smith
john.smith@example.com
|
Engineer | +1 0432 677 943 |
|
Edit |
Beth Springs
beth.springs@example.com
|
Developer | +1 0465 899 443 |
|
Edit |
Peter Knowles
peter.knowles@example.com
|
Programmer | +1 0472 344 565 |
|
Edit |
Sarah Hill
sarah.hill@example.com
|
Marketer | +1 0429 996 220 |
|
Edit |
<.table>
<.tr>
<.th>Name</.th>
<.th>Title</.th>
<.th>Phone</.th>
<.th>Status</.th>
<.th></.th>
</.tr>
<.tr>
<.td>
<.user_inner_td
avatar_assigns={%{src: "https://res.cloudinary.com/wickedsites/image/upload/v1636595188/dummy_data/avatar_2_jhs6ww.png"}}
label="John Smith"
sub_label="john.smith@example.com"
/>
</.td>
<.td>Engineer</.td>
<.td class="whitespace-nowrap">+1 0432 677 943</.td>
<.td>
<.badge color="success" label="Active" />
</.td>
<.td>
<.a to="/" label="Edit" class="text-primary-600 dark:text-primary-400" />
</.td>
</.tr>
<.tr>
<.td>
<.user_inner_td
avatar_assigns={%{src: "https://res.cloudinary.com/wickedsites/image/upload/v1636595188/dummy_data/avatar_1_lc8plf.png"}}
label="Beth Springs"
sub_label="beth.springs@example.com"
/>
</.td>
<.td>Developer</.td>
<.td class="whitespace-nowrap">+1 0465 899 443</.td>
<.td>
<.badge color="warning" label="Pending" />
</.td>
<.td>
<.a to="/" label="Edit" class="text-primary-600 dark:text-primary-400" />
</.td>
</.tr>
<.tr>
<.td>
<.user_inner_td
avatar_assigns={%{src: "https://res.cloudinary.com/wickedsites/image/upload/v1636595189/dummy_data/avatar_14_rkiyfa.png"}}
label="Peter Knowles"
sub_label="peter.knowles@example.com"
/>
</.td>
<.td>Programmer</.td>
<.td class="whitespace-nowrap">+1 0472 344 565</.td>
<.td>
<.badge color="gray" label="Cancelled" />
</.td>
<.td>
<.a to="/" label="Edit" class="text-primary-600 dark:text-primary-400" />
</.td>
</.tr>
<.tr>
<.td>
<.user_inner_td
avatar_assigns={%{src: "https://res.cloudinary.com/wickedsites/image/upload/v1604268092/unnamed_sagz0l.jpg"}}
label="Sarah Hill"
sub_label="sarah.hill@example.com"
/>
</.td>
<.td>Marketer</.td>
<.td class="whitespace-nowrap">+1 0429 996 220</.td>
<.td>
<.badge color="danger" label="Deleted" />
</.td>
<.td>
<.a to="/" label="Edit" class="text-primary-600 dark:text-primary-400" />
</.td>
</.tr>
</.table>
Properties
# <.table>
attr :id, :string
attr :class, :string, default: "", doc: "CSS class"
attr :rows, :list, default: [], doc: "the list of rows to render"
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 slot"
slot :col do
attr :label, :string
attr :class, :string
attr :row_class, :string
end
attr :rest, :global, include: ~w(colspan rowspan)
# <.th>
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global, include: ~w(colspan rowspan))
slot(:inner_block, required: false)
# <.tr>
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
# <.td>
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global, include: ~w(colspan headers rowspan))
slot(:inner_block, required: false)
# <.user_inner_td>
attr(:class, :string, default: "", doc: "CSS class")
attr(:label, :string, default: nil, doc: "Adds a label your user, e.g name")
attr(:sub_label, :string, default: nil, doc: "Adds a sub-label your to your user, e.g title")
attr(:rest, :global)
attr(:avatar_assigns, :map, default: nil, doc: "if using an avatar, this map will be passed to the avatar component as props")