Class: Charming::Components::TabBar

Inherits:
Charming::Component show all
Includes:
KeyboardHandler
Defined in:
lib/charming/presentation/components/tab_bar.rb

Overview

TabBar renders a horizontal list of tabs with one active tab, navigable with left/right (h/l in vim keymap) and selectable with Enter. Mouse clicks select the clicked tab.

TabBar.new(tabs: ["Files", "Search", "Git"], selected_index: 0)

‘handle_key` returns `[:selected, index]` on Enter, `:handled` for navigation keys, and nil otherwise.

Constant Summary collapse

KEY_ACTIONS =

Maps navigation keys to instance methods via KeyboardHandler.

{
  left: :move_left,
  right: :move_right,
  home: :move_home,
  end: :move_end
}.freeze

Constants included from KeyboardHandler

KeyboardHandler::VIM_KEYMAP

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Charming::Component

#captures_text?

Methods inherited from View

#focused?, #layout_assigns

Constructor Details

#initialize(tabs:, selected_index: 0, separator: " ", keymap: :vim, theme: nil) ⇒ TabBar

tabs is the array of tab labels. selected_index is the active tab (default 0). separator spaces the tabs apart.



29
30
31
32
33
34
35
# File 'lib/charming/presentation/components/tab_bar.rb', line 29

def initialize(tabs:, selected_index: 0, separator: "  ", keymap: :vim, theme: nil)
  super(theme: theme)
  @tabs = Array(tabs).map(&:to_s)
  @selected_index = @tabs.empty? ? 0 : selected_index.to_i.clamp(0, @tabs.length - 1)
  @separator = separator
  @keymap = keymap
end

Instance Attribute Details

#selected_indexObject (readonly)

The tab labels and the index of the active tab.



25
26
27
# File 'lib/charming/presentation/components/tab_bar.rb', line 25

def selected_index
  @selected_index
end

#tabsObject (readonly)

The tab labels and the index of the active tab.



25
26
27
# File 'lib/charming/presentation/components/tab_bar.rb', line 25

def tabs
  @tabs
end

Instance Method Details

#handle_key(event) ⇒ Object

Returns ‘[:selected, index]` on Enter; navigation keys move the active tab.



38
39
40
41
42
43
# File 'lib/charming/presentation/components/tab_bar.rb', line 38

def handle_key(event)
  return nil if tabs.empty?
  return [:selected, selected_index] if Charming.key_of(event) == :enter

  super
end

#handle_mouse(event) ⇒ Object

Selects the clicked tab. Returns :handled when a tab was hit, nil otherwise.



46
47
48
49
50
51
52
53
54
55
# File 'lib/charming/presentation/components/tab_bar.rb', line 46

def handle_mouse(event)
  return nil if tabs.empty?
  return nil unless event.respond_to?(:click?) && event.click?

  index = tab_index_at_column(event.x)
  return nil unless index

  @selected_index = index
  :handled
end

#renderObject

Renders the tabs on one row, the active tab in the selected style.



58
59
60
# File 'lib/charming/presentation/components/tab_bar.rb', line 58

def render
  tabs.each_with_index.map { |tab, index| render_tab(tab, index) }.join(@separator)
end