require "rooibos"
require_relative "messages"
module TabBar
include Rooibos::Router
Command = Rooibos::Command
TABS = [:counter, :color].freeze
TAB_LABELS = { counter: " Counters ", color: " Colors " }.freeze
Model = Data.define(:selected_index, :message_count)
Init = -> {
Ractor.make_shareable Model.new(selected_index: 0, message_count: 0)
}
View = -> (model, tui, theme: :cyan) {
titles = TABS.map.with_index do |tab, i|
label = TAB_LABELS[tab]
if i == model.selected_index
tui.text_line(spans: [tui.text_span(content: label, style: tui.style(modifiers: [:bold]))])
else
tui.text_line(spans: [tui.text_span(content: label)])
end
end
tui.tabs(
titles:,
selected_index: model.selected_index,
highlight_style: tui.style(fg: theme, modifiers: [:bold, :reversed]),
block: tui.block(
title: "Messages: #{model.message_count}",
borders: [:all],
border_style: { fg: theme }
)
)
}
receive_events :"[",
-> (_, model) {
new_index = (model.selected_index - 1) % TABS.size
[model.with(selected_index: new_index), Command.bubble(TabSelected.new(tab: TABS[new_index]))]
}
receive_events :"]",
-> (_, model) {
new_index = (model.selected_index + 1) % TABS.size
[model.with(selected_index: new_index), Command.bubble(TabSelected.new(tab: TABS[new_index]))]
}
receive_events :mouse_left_down,
-> (message, model) {
tab_index = (message.x < 14) ? 0 : 1
tab_index = [tab_index, TABS.size - 1].min
return [model, nil] if tab_index == model.selected_index
[model.with(selected_index: tab_index), Command.bubble(TabSelected.new(tab: TABS[tab_index]))]
}
Update = from_router
end