Skip to main content

Table Component for Rails

Table component for Rails. A responsive table for displaying structured data, with zebra striping, sticky headers, and caption and density variants.

Usage

<%= render "components/table" do %>
  <%= render "components/table/header" do %>
    <%= render "components/table/row" do %>
      <%= render "components/table/head" do %>Name<% end %>
      <%= render "components/table/head" do %>Email<% end %>
      <%= render "components/table/head", css_classes: "text-right" do %>Amount<% end %>
    <% end %>
  <% end %>

  <%= render "components/table/body" do %>
    <% @users.each do |user| %>
      <%= render "components/table/row" do %>
        <%= render "components/table/cell" do %><%= user.name %><% end %>
        <%= render "components/table/cell" do %><%= user.email %><% end %>
        <%= render "components/table/cell", css_classes: "text-right" do %><%= user.amount %><% end %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

Examples

With Footer

<%= render "components/table" do %>
  <%= render "components/table/header" do %>
    <%# ... %>
  <% end %>
  <%= render "components/table/body" do %>
    <%# ... %>
  <% end %>
  <%= render "components/table/footer" do %>
    <%= render "components/table/row" do %>
      <%= render "components/table/cell", colspan: 2 do %>Total<% end %>
      <%= render "components/table/cell", css_classes: "text-right" do %>$750.00<% end %>
    <% end %>
  <% end %>
<% end %>

Selected Row

<%= render "components/table/row", selected: true do %>
  <%= render "components/table/cell" do %>Selected item<% end %>
<% end %>

Bordered Variant

Draws a border around the scroll container.

<%= render "components/table", variant: :bordered do %>
  <%# ... %>
<% end %>

Striped Variant

Alternates row backgrounds on the table itself.

<%= render "components/table", table_variant: :striped do %>
  <%# ... %>
<% end %>

Simple Table Helper

For collection-driven tables, the simple_table helper renders the whole structure from a column definition. Keys can be attribute names, hash keys, or procs.

<%= simple_table @invoices, caption: "Recent invoices", columns: [
  { key: :number, label: "Invoice" },
  { key: :customer, label: "Customer" },
  { key: ->(i) { i.amount.format }, label: "Amount", align: :right }
], row_id: :id, table_variant: :striped %>

API Reference

Every table partial passes unknown keywords through as HTML attributes, so standard table attributes like colspan and rowspan work directly on cells, and id, aria, or data attributes work on any part.

Table

The table renders two elements: a scrollable container div and the table element inside it. The variant parameter styles the container (that is why :bordered lives there), while table_variant styles the table element itself.

Parameter Type Default Description
container Boolean true Wrap in scrollable container; with false, variant has no element to style and is ignored
variant Symbol nil Container variant, :bordered draws a border around the scroll container
table_variant Symbol nil Table variant, :striped alternates row backgrounds
css_classes String "" Additional CSS classes
html_options Hash {} Additional HTML attributes

Table Header

Parameter Type Default Description
sticky Boolean false Sticky header on scroll
css_classes String "" Additional CSS classes
html_options Hash {} Additional HTML attributes

Table Row

Parameter Type Default Description
selected Boolean false Highlight as selected
css_classes String "" Additional CSS classes
html_options Hash {} Additional HTML attributes

Table Head

Parameter Type Default Description
text String nil Heading text
content String nil Captured HTML via capture, or use block
scope String "col" Scope attribute for accessibility; pass nil to omit it
css_classes String "" Additional CSS classes
html_options Hash {} Additional HTML attributes

Table Cell

Parameter Type Default Description
text String nil Cell text
content String nil Captured HTML via capture, or use block
css_classes String "" Additional CSS classes
html_options Hash {} Additional HTML attributes, e.g. colspan, rowspan

simple_table Helper

Parameter Type Default Description
collection Enumerable required Objects or hashes to render
columns Array required Hashes with key (attribute, hash key, or proc), label, and optional align (:center, :right; left by default)
caption String nil Table caption
variant Symbol nil Container variant, :bordered
table_variant Symbol nil Table variant, :striped
empty_message String "No data available" Shown when the collection is empty
row_id Symbol nil Method used to build each row id, row-{value}
html_options Hash {} Additional HTML attributes for the table element, passed as bare keywords

The helper renders the components/simple_table partial, which accepts the same locals (with collection: as a keyword) if you prefer render.

Table Body / Footer / Caption

Caption also accepts text and content like cell and head.

Parameter Type Default Description
css_classes String "" Additional CSS classes
html_options Hash {} Additional HTML attributes

Helper Methods

Method Description
simple_table(collection, columns:, caption: nil, variant: nil, table_variant: nil, empty_message: "No data available", row_id: nil, **html_options) Renders a full table from a collection
table_alignment_class(align) Returns "text-right" for :right, "text-center" for :center, nil otherwise
table_data_attrs(variant: nil) { data: { component: "table", variant: } } for a hand-built table element
table_container_data_attrs(variant: nil) { data: { table_part: "container", variant: } }
table_header_data_attrs(sticky: false) { data: { table_part: "header", sticky: "true" } }
table_row_data_attrs(selected: false) { data: { table_part: "row", state: "selected" } }
table_cell_data_attrs(empty: false) { data: { table_part: "cell", empty: "true" } }
table_head_data_attrs, table_body_data_attrs, table_footer_data_attrs, table_caption_data_attrs { data: { table_part: "head" | "body" | "footer" | "caption" } }

The optional keys (variant, sticky, state, empty) are only included when the argument is set.