Table
UI::TableA styled table with header, rows and caption.
# VelvetKit
## Table (`UI::Table`)
A styled table with header, rows and caption.
Add it: `bin/rails generate velvetkit:add table`
### Arguments
```ruby
UI::Table.new(caption: nil, class: nil, **html_attrs)
```
Slots: `with_head`, `with_row`, `with_empty_state`, `with_column`, `with_cell`
### Notes
UI::Table — a data table.
Lists get long and phones are narrow, so the table is always wrapped in a
horizontal scroll container rather than allowed to break the page layout.
Usage:
<%= render(UI::Table.new(caption: "Invoices")) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Customer" } %>
<% head.with_column(align: :end) { "Amount" } %>
<% end %>
<% @invoices.each do |invoice| %>
<% table.with_row do |row| %>
<% row.with_cell { invoice.customer.name } %>
<% row.with_cell(align: :end) { number_to_currency(invoice.amount) } %>
<% end %>
<% end %>
<% table.with_empty_state { "No invoices yet" } %>
<% end %>
### Example: Customers
```erb
<%= render(UI::Table.new) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Customer" } %>
<% head.with_column { "Plan" } %>
<% head.with_column(align: :end) { "Seats" } %>
<% end %>
<% [ [ "Aditi Rao", "Business", "24" ], [ "Arjun Nair", "Team", "8" ],
[ "Chitra Menon", "Free", "1" ] ].each do |name, plan, seats| %>
<% table.with_row do |row| %>
<% row.with_cell { name } %>
<% row.with_cell { plan } %>
<% row.with_cell(align: :end) { seats } %>
<% end %>
<% end %>
<% end %>
```
### Example: Empty
```erb
<%# An empty table should say so rather than show a bare header. %>
<%= render(UI::Table.new) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Customer" } %>
<% head.with_column(align: :end) { "Amount" } %>
<% end %>
<% table.with_empty_state { "No invoices yet" } %>
<% end %>
```
### Example: With Caption And Selection
```erb
<%= render(UI::Table.new(caption: "Invoices this month — 2 open")) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Invoice" } %>
<% head.with_column(align: :end) { "Amount" } %>
<% end %>
<% table.with_row(selected: true) do |row| %>
<% row.with_cell { "INV-104" } %>
<% row.with_cell(align: :end) { "₹12,400" } %>
<% end %>
<% table.with_row do |row| %>
<% row.with_cell { "INV-105" } %>
<% row.with_cell(align: :end) { "₹8,250" } %>
<% end %>
<% end %>
```
bin/rails generate velvetkit:add table
- Also adds
- Nothing else
- Stimulus
- None, it's server-rendered
- Installs
- Nothing
Examples
Customers
| Customer | Plan | Seats |
|---|---|---|
| Aditi Rao | Business | 24 |
| Arjun Nair | Team | 8 |
| Chitra Menon | Free | 1 |
customers.html.erb
<%= render(UI::Table.new) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Customer" } %>
<% head.with_column { "Plan" } %>
<% head.with_column(align: :end) { "Seats" } %>
<% end %>
<% [ [ "Aditi Rao", "Business", "24" ], [ "Arjun Nair", "Team", "8" ],
[ "Chitra Menon", "Free", "1" ] ].each do |name, plan, seats| %>
<% table.with_row do |row| %>
<% row.with_cell { name } %>
<% row.with_cell { plan } %>
<% row.with_cell(align: :end) { seats } %>
<% end %>
<% end %>
<% end %>
Empty
| Customer | Amount |
|---|---|
| No invoices yet | |
empty.html.erb
<%# An empty table should say so rather than show a bare header. %>
<%= render(UI::Table.new) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Customer" } %>
<% head.with_column(align: :end) { "Amount" } %>
<% end %>
<% table.with_empty_state { "No invoices yet" } %>
<% end %>
With Caption And Selection
| Invoice | Amount |
|---|---|
| INV-104 | ₹12,400 |
| INV-105 | ₹8,250 |
with_caption.html.erb
<%= render(UI::Table.new(caption: "Invoices this month — 2 open")) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Invoice" } %>
<% head.with_column(align: :end) { "Amount" } %>
<% end %>
<% table.with_row(selected: true) do |row| %>
<% row.with_cell { "INV-104" } %>
<% row.with_cell(align: :end) { "₹12,400" } %>
<% end %>
<% table.with_row do |row| %>
<% row.with_cell { "INV-105" } %>
<% row.with_cell(align: :end) { "₹8,250" } %>
<% end %>
<% end %>
API
Arguments
UI::Table.new(caption: nil, class: nil, **html_attrs)
Slots:
with_head
with_row
with_empty_state
with_column
with_cell
Notes
UI::Table — a data table.
Lists get long and phones are narrow, so the table is always wrapped in a
horizontal scroll container rather than allowed to break the page layout.
Usage:
<%= render(UI::Table.new(caption: "Invoices")) do |table| %>
<% table.with_head do |head| %>
<% head.with_column { "Customer" } %>
<% head.with_column(align: :end) { "Amount" } %>
<% end %>
<% @invoices.each do |invoice| %>
<% table.with_row do |row| %>
<% row.with_cell { invoice.customer.name } %>
<% row.with_cell(align: :end) { number_to_currency(invoice.amount) } %>
<% end %>
<% end %>
<% table.with_empty_state { "No invoices yet" } %>
<% end %>