Class: Charming::Components::List
- Inherits:
-
Charming::Component
- Object
- View
- Charming::Component
- Charming::Components::List
- Includes:
- KeyboardHandler
- Defined in:
- lib/charming/presentation/components/list.rb
Overview
List is a vertically-scrollable selectable list. Supports keyboard navigation (up/down/home/end, Enter to activate) and mouse click selection. When a height is given, the list renders a fixed-height window over its items with auto-scroll keeping the selected item in view.
Direct Known Subclasses
Constant Summary collapse
- KEY_ACTIONS =
Maps navigation key symbols to instance methods consumed by the KeyboardHandler mixin: :up moves selection up, :down moves down, :home jumps to first item, :end jumps to last. See Viewport#KEY_ACTIONS and Table#KEY_ACTIONS for identical pattern.
{ up: :move_up, down: :move_down, home: :move_home, end: :move_end }.freeze
Constants included from KeyboardHandler
Instance Attribute Summary collapse
-
#filter ⇒ Object
The currently selected index (within the filtered view) and active filter query.
-
#selected_index ⇒ Object
readonly
The currently selected index (within the filtered view) and active filter query.
Instance Method Summary collapse
-
#handle_key(event) ⇒ Object
Handles key events.
-
#handle_mouse(event) ⇒ Object
Handles mouse events: a click within the visible window selects the clicked row.
-
#initialize(items:, selected_index: 0, height: nil, label: nil, theme: nil, keymap: :vim, filter: nil) ⇒ List
constructor
items is the array of selectable objects.
-
#items ⇒ Object
The visible items: the source list narrowed by the active filter (best fuzzy match first), or the full source list when no filter is set.
-
#render ⇒ Object
Renders the visible window of items, prefixing each with "> " (and applying the selected style) or " ".
-
#selected_item ⇒ Object
Returns the currently selected item, or nil when the list is empty.
Methods inherited from Charming::Component
Methods inherited from View
Constructor Details
#initialize(items:, selected_index: 0, height: nil, label: nil, theme: nil, keymap: :vim, filter: nil) ⇒ List
items is the array of selectable objects. selected_index defaults to 0.
height optionally constrains the visible window; label is a callable that
extracts the display string from an item (defaults to to_s).
keymap selects the keybinding style (:vim enables h/j/k/l → left/down/up/right).
filter optionally narrows items by fuzzy-matching the label (see FuzzyMatcher);
navigation, rendering, and selection all operate on the filtered view.
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/charming/presentation/components/list.rb', line 31 def initialize(items:, selected_index: 0, height: nil, label: nil, theme: nil, keymap: :vim, filter: nil) super(theme: theme) @source_items = items @selected_index = selected_index @height = height @label = label || :to_s.to_proc @keymap = keymap @filter = filter clamp_position end |
Instance Attribute Details
#filter ⇒ Object
The currently selected index (within the filtered view) and active filter query.
23 24 25 |
# File 'lib/charming/presentation/components/list.rb', line 23 def filter @filter end |
#selected_index ⇒ Object (readonly)
The currently selected index (within the filtered view) and active filter query.
23 24 25 |
# File 'lib/charming/presentation/components/list.rb', line 23 def selected_index @selected_index end |
Instance Method Details
#handle_key(event) ⇒ Object
Handles key events. Returns [:selected, item] on Enter when an item is selected;
otherwise delegates to the KeyboardHandler for navigation keys.
59 60 61 62 63 |
# File 'lib/charming/presentation/components/list.rb', line 59 def handle_key(event) return [:selected, selected_item] if Charming.key_of(event) == :enter && selected_item super end |
#handle_mouse(event) ⇒ Object
Handles mouse events: a click within the visible window selects the clicked row. Returns :handled on a successful click, nil otherwise.
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/charming/presentation/components/list.rb', line 67 def handle_mouse(event) return nil unless @height return nil unless event.respond_to?(:click?) && event.click? clicked = event.y return nil if clicked.negative? || clicked >= visible_items.length @selected_index = + clicked clamp_position :handled end |
#items ⇒ Object
The visible items: the source list narrowed by the active filter (best fuzzy match first), or the full source list when no filter is set.
44 45 46 47 48 |
# File 'lib/charming/presentation/components/list.rb', line 44 def items return @source_items if filter.nil? || filter.to_s.empty? FuzzyMatcher.filter(filter, @source_items, &@label) end |
#render ⇒ Object
Renders the visible window of items, prefixing each with "> " (and applying the selected style) or " ".
86 87 88 89 90 |
# File 'lib/charming/presentation/components/list.rb', line 86 def render visible_items.each_with_index.map do |item, index| render_item(item, + index) end.join("\n") end |
#selected_item ⇒ Object
Returns the currently selected item, or nil when the list is empty.
80 81 82 |
# File 'lib/charming/presentation/components/list.rb', line 80 def selected_item items[selected_index] end |