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:
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" } }
endRow controls
-> resource_row_controls_config
Global default for row controls across all resources. Individual resources override it with row_controls_config.
Avo.configure do |config|
config.resource_row_controls_config = {
placement: :right,
float: false,
show_on_hover: false
}
end- Type: Hash with keys
placement,float,show_on_hover - Default:
{ placement: :right, float: false, show_on_hover: false }
-> 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.
class Avo::Resources::User < Avo::BaseResource
self.row_controls_config = {
placement: :left
}
end- Type: Hash with keys
placement,float,show_on_hover - Default:
{}(falls back to the global configuration)
-> placement
The position of the row controls within the row.
- Type: Symbol
- Default:
:right - Values:
| Value | Behavior |
|---|---|
:right | Controls on the right side of the row |
:left | Controls on the left side of the row |
:both | Controls 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.
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
ArgumentErrorif 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 viaAvo.loggerand 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).
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 => Booleanpairs (like Rails'class_nameshelper);nil/falseto skip - Validation: any other type raises
ArgumentError
-> data
A hash of data-* attributes, deep-merged with Avo's existing data attributes:
data-controlleranddata-actionare 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.
data: -> { { test_id: "message-#{record.id}", controller: "highlightable" } }- Type: Hash;
nil/falseto skip - Validation: any other type raises
ArgumentError
-> style
Inline CSS style string. Passed through to the <tr>, HTML-escaped by Rails.
style: -> { "border-left: 4px solid #{record.priority_color};" }- Type: String, Symbol, or Integer (Symbols and Integers are converted to strings);
nil/falseto omit - Validation: any other type — including
true— raisesArgumentError. 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.
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:
| Attribute | Reason |
|---|---|
id | Avo emits <tr id="..."> for tests and Stimulus targeting |
role | The implicit role="row" on <tr> inside <table> is canonical; overriding breaks screen-reader semantics |
aria-selected | Owned by Avo's row-selection state |
on* event handlers (onclick, onmouseover, …) | Use Stimulus actions via data: { action: "..." } instead |
tabindex, contenteditable, draggable | Conflict 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.