Module: Layered::Ui::TableHelper
- Defined in:
- app/helpers/layered/ui/table_helper.rb
Instance Method Summary collapse
-
#l_ui_format_datetime(value) ⇒ Object
Formats a date/time value for display in a table cell.
-
#l_ui_table(records, columns:, caption: nil, actions: nil, actions_label: "Actions", query: nil, url: nil, turbo_frame: nil, row_id: nil) ⇒ Object
Renders a styled, accessible data table.
Instance Method Details
#l_ui_format_datetime(value) ⇒ Object
Formats a date/time value for display in a table cell.
l_ui_format_datetime(record.created_at) # => "15 Apr 2026, 10:30"
7 8 9 |
# File 'app/helpers/layered/ui/table_helper.rb', line 7 def l_ui_format_datetime(value) value&.strftime("%-d %b %Y, %H:%M") end |
#l_ui_table(records, columns:, caption: nil, actions: nil, actions_label: "Actions", query: nil, url: nil, turbo_frame: nil, row_id: 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. Every column must supply a render: proc that receives a record and returns cell content - the helper does not extract or format data itself.
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) Used for label generation and sort links.
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) Required. Receives (record), returns cell content.
Pass query: (a Ransack search object) and turbo_frame: to enable sortable column headers via l_ui_sort_link.
Each <tr> is given id: dom_id(record) when the record responds to to_key (i.e. ActiveRecord), so individual rows can be targeted by Turbo Streams. Pass row_id: as a proc to override (return nil to omit the id).
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 72 73 74 75 76 77 78 79 80 |
# File 'app/helpers/layered/ui/table_helper.rb', line 41 def l_ui_table(records, columns:, caption: nil, actions: nil, actions_label: "Actions", query: nil, url: nil, turbo_frame: nil, row_id: 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(id: table_row_id(record, row_id)) 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") end |