Skip to content
How-to guides and worked examplesSee the guides →

Table view API

Per-option reference for the table view. For task-oriented documentation and worked examples, see the Table view guide.

Row controls options live in config/initializers/avo.rb (globally) or on the resource class; row styling lives on the resource class:

ruby
Avo.configure do |config|
  config.resource_row_controls_config = { placement: :right }
end

class Avo::Resources::User < Avo::BaseResource
  self.row_controls_config = { placement: :left }
  self.table_view = { row_options: { class: "bg-blue-50" } }
end

Row controls

resource_row_controls_config

Global default for row controls across all resources. Individual resources override it with row_controls_config.

ruby
Avo.configure do |config|
  config.resource_row_controls_config = {
    placement: :right,
    float: false,
    show_on_hover: false
  }
end

row_controls_config

Per-resource row controls configuration. Merged over resource_row_controls_config, so you only need to set the keys you want to change.

ruby
class Avo::Resources::User < Avo::BaseResource
  self.row_controls_config = {
    placement: :left
  }
end

placement

The position of the row controls within the row.

  • Type: Symbol
  • Default: :right
  • Values:
ValueBehavior
:rightControls on the right side of the row
:leftControls on the left side of the row
:bothControls on both sides of the row

WARNING

float and show_on_hover are designed to function optimally when placement is :right. Avo does not restrict their usage with :left or :both, but the applied styles are intended for :right and unexpected behavior may occur with other placements.

float

Whether the row controls float over the row (sticky to the row end, with a gradient fade) instead of occupying their own column.

  • Type: Boolean
  • Default: false

show_on_hover

Whether the row controls are hidden until the row is hovered.

  • Type: Boolean
  • Default: false

Row styling

table_view

Resource class attribute holding table view configuration. Currently supports one key: row_options.

ruby
class Avo::Resources::Message < Avo::BaseResource
  self.table_view = {
    row_options: { class: "bg-blue-50" }
  }
end
  • Type: Hash
  • Default: nil

row_options

HTML attributes applied to the <tr> element of each record on the Index view and in has_many association tables.

Each value may be static or a Proc; the whole hash itself may also be a Proc returning a hash. Procs are evaluated once per row, per render, through Avo::ExecutionContext with access to record, resource, view (:index on the main index, :has_many inside an association panel), and the standard defaults (current_user, params, request, view helpers).

Returning nil or false from a value omits that attribute (for class:, it leaves Avo's classes untouched).

  • Type: Hash, or Proc returning a Hash
  • Default: nil
  • Values: class, data, style, and other passthrough HTML attributes — see below
  • Validation: raises ArgumentError if the top level doesn't resolve to a Hash, if a denied key is set, or if a value has an unsupported type. Errors raise outside production; in production the violation is logged via Avo.logger and the row falls back to Avo's default attributes.

Supported keys

class

CSS classes appended to Avo's row classes. Because they're appended after Avo's, they win at equal CSS specificity. Avo never strips its own utility classes (notably cursor-pointer when click-to-view is enabled).

ruby
class: "bg-yellow-50"                                            # String
class: -> { record.flagged? ? ["ring-2", "ring-red-300"] : [] }  # Array
class: -> { { "opacity-60" => record.archived? } }               # Hash
  • Type: String, Symbol, Array, or Hash of class => Boolean pairs (like Rails' class_names helper); nil/false to skip
  • Validation: any other type raises ArgumentError

data

A hash of data-* attributes, deep-merged with Avo's existing data attributes:

  • data-controller and data-action are token-concatenated — your Stimulus identifiers are added alongside Avo's, never replacing them.
  • Reserved keys are protected — attempts to set them are ignored with a warning in development and test.
  • Other keys pass through, subject to the same value coercion as any attribute.
ruby
data: -> { { test_id: "message-#{record.id}", controller: "highlightable" } }
  • Type: Hash; nil/false to skip
  • Validation: any other type raises ArgumentError

style

Inline CSS style string. Passed through to the <tr>, HTML-escaped by Rails.

ruby
style: -> { "border-left: 4px solid #{record.priority_color};" }
  • Type: String, Symbol, or Integer (Symbols and Integers are converted to strings); nil/false to omit
  • Validation: any other type — including true — raises ArgumentError. Convert booleans with .to_s.

Other HTML attributes

Any other HTML attribute (title, aria-label, …) is passed through unchanged, except the denied attributes below. Values are HTML-escaped by Rails' content_tag and follow the same coercion rules as style.

ruby
title: -> { "Created #{time_ago_in_words(record.created_at)} ago" }
"aria-label": -> { "Message from #{record.role}" }

Reserved data keys

Avo owns these data-* keys on <tr>. Attempts to set them are ignored; in development and test a warning is logged via Avo.logger.

index, component_name, resource_name, record_id, resource_id, visit_path, reorder_target

Denied attributes

Some attributes are off-limits because Avo owns them or they break behavior:

AttributeReason
idAvo emits <tr id="..."> for tests and Stimulus targeting
roleThe implicit role="row" on <tr> inside <table> is canonical; overriding breaks screen-reader semantics
aria-selectedOwned by Avo's row-selection state
on* event handlers (onclick, onmouseover, …)Use Stimulus actions via data: { action: "..." } instead
tabindex, contenteditable, draggableConflict with Avo's keyboard navigation and selection

Setting any of these raises ArgumentError listing the supported keys. In production, the row falls back to Avo's defaults and the violation is logged via Avo.logger instead.