Module: Layered::Ui::TableHelper
- Defined in:
- app/helpers/layered/ui/table_helper.rb
Instance Method Summary collapse
-
#l_ui_table(records, columns:, caption: nil, actions: nil, actions_label: "Actions", query: nil, url: nil, turbo_frame: nil) ⇒ Object
Renders a styled, accessible data table.
Instance Method Details
#l_ui_table(records, columns:, caption: nil, actions: nil, actions_label: "Actions", query: nil, url: nil, turbo_frame: nil) ⇒ Object
Renders a styled, accessible data table.
Use this helper in any view to render a table with the engine’s l-ui-table styles. It supports custom cell rendering via procs, an optional actions column, and Ransack sort links.
l_ui_table(@personas,
columns: [
{ attribute: :name, primary: true, render: ->(r) { link_to r.name, persona_path(r) } },
{ attribute: :description, render: ->(r) { truncate(r.description, length: 60) } },
],
actions: ->(r) { link_to "Edit", edit_persona_path(r) },
caption: "Personas"
)
Column options:
attribute: (Symbol) Model attribute for data and label generation.
label: (String) Custom header text. Defaults to humanised attribute.
primary: (Boolean) Renders as <th scope="row">. Defaults to first column.
sortable: (Boolean) Show sort link when query: is provided. Defaults to true.
render: (Proc) Receives (record), returns cell content.
When no render: proc is given, the cell value is extracted via record[attribute] for hashes or record.public_send(attribute) for objects, with automatic date formatting.
Pass query: (a Ransack search object) and turbo_frame: to enable sortable column headers via l_ui_sort_link.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'app/helpers/layered/ui/table_helper.rb', line 32 def l_ui_table(records, columns:, caption: nil, actions: nil, actions_label: "Actions", query: nil, url: nil, turbo_frame: nil) columns = normalise_table_columns(columns) col_count = columns.size + (actions ? 1 : 0) thead = tag.thead(class: "l-ui-table__header") do tag.tr do cells = columns.map do |col| if col[:sortable] && query l_ui_sort_link(query, col[:attribute], col[:label], url: url, turbo_frame: turbo_frame) else tag.th(col[:label], class: "l-ui-table__header-cell", scope: "col") end end cells << tag.th(actions_label, class: "l-ui-table__header-cell--action", scope: "col") if actions safe_join(cells) end end tbody = tag.tbody(class: "l-ui-table__body") do if records.empty? tag.tr do tag.td("No records found.", class: "l-ui-table__cell", colspan: col_count) end else safe_join(records.map do |record| tag.tr do cells = columns.map do |col| table_cell(record, col) end cells << tag.td(class: "l-ui-table__cell--action") { actions.call(record) } if actions safe_join(cells) end end) end end caption_tag = caption ? tag.caption(caption, class: "l-ui-sr-only") : nil table = tag.table(class: "l-ui-table") { safe_join([caption_tag, thead, tbody].compact) } tag.div(table, class: "l-ui-container--table l-ui-utility--mt-lg") end |