Class: Charming::Presentation::Components::Table
- Inherits:
-
Charming::Presentation::Component
- Object
- View
- Charming::Presentation::Component
- Charming::Presentation::Components::Table
- Includes:
- KeyboardHandler
- Defined in:
- lib/charming/presentation/components/table.rb
Overview
Table renders tabular data with a header row, a selected row highlight, and keyboard navigation. Mouse clicks within the body area also select rows. The table is rendered via tty-table and the selected row is overlaid with reverse-video ANSI styling.
Constant Summary collapse
- KEY_ACTIONS =
Maps navigation keys to the instance methods that move the selection. Shared with List and Viewport via KeyboardHandler.
{ up: :move_up, down: :move_down, home: :move_home, end: :move_end }.freeze
- HEADER_HEIGHT =
Number of terminal rows occupied by the table’s top border and header line. Used by the mouse handler to translate absolute row coordinates to body rows.
2
Constants included from KeyboardHandler
Instance Attribute Summary collapse
-
#header ⇒ Object
readonly
The header row, the body rows, and the currently selected row index, respectively.
-
#rows ⇒ Object
readonly
The header row, the body rows, and the currently selected row index, respectively.
-
#selected_index ⇒ Object
readonly
The header row, the body rows, and the currently selected row index, respectively.
Instance Method Summary collapse
-
#handle_key(event) ⇒ Object
Handles key events.
-
#handle_mouse(event) ⇒ Object
Handles mouse events: a click within the body area selects the clicked row.
-
#initialize(header:, rows: [], selected_index: 0, keymap: :vim) ⇒ Table
constructor
header is an array of column labels.
-
#render ⇒ Object
Renders the table to a string.
-
#selected_row ⇒ Object
Returns the currently selected row, or nil when the table is empty.
Methods inherited from View
Constructor Details
#initialize(header:, rows: [], selected_index: 0, keymap: :vim) ⇒ Table
header is an array of column labels. rows is the array of body rows (each either a String, an Array, or a Hash of column-value pairs). selected_index defaults to 0. keymap selects the keybinding style (‘:vim` enables h/j/k/l → left/down/up/right).
33 34 35 36 37 38 39 |
# File 'lib/charming/presentation/components/table.rb', line 33 def initialize(header:, rows: [], selected_index: 0, keymap: :vim) super() @header = Array(header).map(&:to_s) @rows = Array(rows) @selected_index = clamp_index(selected_index) @keymap = keymap end |
Instance Attribute Details
#header ⇒ Object (readonly)
The header row, the body rows, and the currently selected row index, respectively.
28 29 30 |
# File 'lib/charming/presentation/components/table.rb', line 28 def header @header end |
#rows ⇒ Object (readonly)
The header row, the body rows, and the currently selected row index, respectively.
28 29 30 |
# File 'lib/charming/presentation/components/table.rb', line 28 def rows @rows end |
#selected_index ⇒ Object (readonly)
The header row, the body rows, and the currently selected row index, respectively.
28 29 30 |
# File 'lib/charming/presentation/components/table.rb', line 28 def selected_index @selected_index end |
Instance Method Details
#handle_key(event) ⇒ Object
Handles key events. Returns ‘[:selected, row]` on Enter; otherwise delegates to the KeyboardHandler for navigation keys.
43 44 45 46 47 48 49 50 |
# File 'lib/charming/presentation/components/table.rb', line 43 def handle_key(event) return nil if rows.empty? case Charming.key_of(event) when :enter then [:selected, selected_row] else super end end |
#handle_mouse(event) ⇒ Object
Handles mouse events: a click within the body area selects the clicked row. Returns :handled on a successful click.
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/charming/presentation/components/table.rb', line 54 def handle_mouse(event) return nil if rows.empty? return nil unless event.respond_to?(:click?) && event.click? clicked = event.y - HEADER_HEIGHT return nil if clicked.negative? || clicked >= rows.length @selected_index = clicked :handled end |
#render ⇒ Object
Renders the table to a string. Returns a placeholder when both header and rows are empty.
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/charming/presentation/components/table.rb', line 71 def render return "(empty table)" if header.empty? && rows.empty? normalized = rows.map { |row| normalize_row(row) } lines = TTY::Table.new(header: header, rows: normalized) .render(:unicode) .lines(chomp: true) compact_layout(lines) end |
#selected_row ⇒ Object
Returns the currently selected row, or nil when the table is empty.
66 67 68 |
# File 'lib/charming/presentation/components/table.rb', line 66 def selected_row rows[selected_index] end |