tabstrip.lua
#!/usr/bin/env lua
local TabStrip = require("src.terminal.ui.panel.tab_strip")
local Set = require("src.terminal.ui.panel.set")
local terminal = require("terminal")
local Screen = require("src.terminal.ui.panel.screen")
local Panel = require("src.terminal.ui.panel")
local Bar = require("src.terminal.ui.panel.bar")
local TextPanel = require("src.terminal.ui.panel.text")
local tab_contents = {
overview = {
"Welcome to the TabStrip Example!",
"",
"This example demonstrates:",
"",
"• TabStrip panel for displaying tab labels",
"• PanelSet for managing tab content panels",
"• Integration between TabStrip and PanelSet",
"• Keyboard navigation between tabs",
"",
"Use the following keys to navigate:",
"• Left/Right arrows or h/l to switch tabs",
"• Tab/Shift+Tab to move between tabs",
"• q to quit",
"",
"The TabStrip automatically handles:",
"• Viewport scrolling when tabs overflow",
"• Visual highlighting of selected tab",
"• Smooth navigation between tabs",
},
features = {
"TabStrip Features:",
"",
"• Horizontal tab label display",
"• Viewport scrolling for many tabs",
"• Configurable prefix/postfix (default: [])",
"• Customizable attributes for selected/unselected tabs",
"• Callback support for selection changes",
"• Methods: select(), select_next(), select_prev()",
"",
"PanelSet Features:",
"",
"• Manages multiple named panels",
"• Shows one panel at a time",
"• Automatic selection management",
"• Methods: select(), get_selected(), add(), remove()",
"",
"Integration:",
"",
"• TabStrip select_cb connects to PanelSet:select()",
"• Keyboard input controls TabStrip selection",
"• PanelSet automatically shows/hides panels",
},
content = {
"Content Tab",
"",
"This is the content tab. You can put any panel content here.",
"",
"The panels in the PanelSet can be:",
"• TextPanel (like this one)",
"• Regular Panel with custom content",
"• Nested panels with complex layouts",
"",
"Each tab can have completely different content and layout.",
"",
"Try switching between tabs to see different content!",
},
settings = {
"Settings Tab",
"",
"This tab could contain:",
"• Configuration options",
"• User preferences",
"• Application settings",
"",
"For this example, it's just another TextPanel.",
"",
"In a real application, you might have:",
"• Input fields",
"• Checkboxes",
"• Dropdown menus",
"• Other interactive elements",
},
help = {
"Help Tab",
"",
"Keyboard Shortcuts:",
"",
"Navigation:",
" ← / h - Previous tab",
" → / l - Next tab",
" Tab - Next tab",
" Shift+Tab - Previous tab",
"",
"General:",
" q / Q - Quit application",
"",
"The TabStrip will automatically scroll to show",
"the selected tab if there are many tabs.",
}
}
local tab_panels = {}
for tab_id, content in pairs(tab_contents) do
tab_panels[tab_id] = TextPanel {
name = tab_id,
lines = content,
scroll_step = 1,
text_attr = { fg = "white", brightness = "bright" },
border = { format = terminal.draw.box_fmt.single },
auto_render = true,
min_height = 1, min_width = 4, }
end
local tab_set = Set {
children = {
tab_panels.overview,
tab_panels.features,
tab_panels.content,
tab_panels.settings,
tab_panels.help,
},
selected = "overview",
}
local tab_strip = TabStrip {
items = {
{ id = "overview", label = "Overview" },
{ id = "features", label = "Features" },
{ id = "content", label = "Content" },
{ id = "settings", label = "Settings" },
{ id = "help", label = "Help" },
},
selected = "overview",
attr = { fg = "white", bg = "black" },
selected_attr = { fg = "black", bg = "cyan", brightness = "bright" },
select_cb = function(self, tab_id)
tab_set:select(tab_id)
end,
auto_render = true,
padding = 2,
prefix = "┌",
postfix = "┐",
}
local screen = Screen {
header = Panel { orientation = Panel.orientations.vertical,
children = {
Bar {
left = {
text = "TabStrip Example",
attr = { fg = "cyan", brightness = "bright" }
},
center = {
text = "Tabbed Interface Demo",
attr = { fg = "yellow", brightness = "bright", underline = true }
},
right = {
text = "Press 'q' to quit",
attr = { fg = "green", brightness = "bright" }
},
attr = { bg = "blue" }
},
tab_strip
},
split_ratio = 0.6, },
body = tab_set,
footer = Bar {
left = {
text = "←/→ or h/l: switch tabs",
attr = { fg = "magenta", brightness = "bright" }
},
center = {
text = "Tab/Shift+Tab: navigate",
attr = { fg = "yellow", brightness = "bright" }
},
right = {
text = "q: quit",
attr = { fg = "red", brightness = "bright" }
},
attr = { bg = "black", fg = "white" }
}
}
local function main()
local keymap = terminal.input.keymap.default_key_map
local keys = terminal.input.keymap.default_keys
terminal.cursor.visible.set(false)
screen:calculate_layout()
screen:render()
while true do
local key = terminal.input.readansi(0.1)
local keyname = keymap[key or ""]
if key == "q" or key == "Q" then
break
elseif key == "h" or keyname == keys.left then
tab_strip:select_prev()
screen:calculate_layout() screen:render()
elseif key == "l" or keyname == keys.right then
tab_strip:select_next()
screen:calculate_layout() screen:render()
elseif keyname == keys.tab then
tab_strip:select_next()
screen:calculate_layout() screen:render()
elseif keyname == keys.shift_tab then
tab_strip:select_prev()
screen:calculate_layout() screen:render()
end
screen:check_resize(true)
end
end
terminal.initwrap(main, {
displaybackup = true,
filehandle = io.stdout,
})()