1
0
Fork
You've already forked tcellplus
0
tcellplus is a wrapper for the tcell/v3 library adding prebuilt widgets and misc features
  • Go 100%
2026年02月26日 08:48:58 +01:00
examples feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
app.go feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
box.go initial commit 2026年02月25日 16:37:11 -03:00
colors.go initial commit 2026年02月25日 16:37:11 -03:00
command.go feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
confirm.go feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
flex.go initial commit 2026年02月25日 16:37:11 -03:00
focus.go feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
go.mod initial commit 2026年02月25日 16:37:11 -03:00
go.sum initial commit 2026年02月25日 16:37:11 -03:00
input.go initial commit 2026年02月25日 16:37:11 -03:00
keymap.go feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
LICENSE fix: pkg.go.dev should properly find the license now 2026年02月26日 08:48:58 +01:00
NOTICE initial commit 2026年02月25日 16:37:11 -03:00
README.md feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
style.go initial commit 2026年02月25日 16:37:11 -03:00
table.go fix: correct table active index calculation for empty tables and add a test case for drawing empty tables. 2026年02月26日 04:44:30 -03:00
tcellplus_test.go fix: correct table active index calculation for empty tables and add a test case for drawing empty tables. 2026年02月26日 04:44:30 -03:00
text.go feat: implement a flexible keybinding and command system, and enhance Table with sorting, row styling, column alignment, and keymap integration. 2026年02月26日 03:31:27 -03:00
widget.go initial commit 2026年02月25日 16:37:11 -03:00

tcellplus

A minimal TUI widget library built on top of tcell/v3.

installation

go get codeberg.org/joetroll/tcellplus

concepts

Widget is the core interface:

typeWidgetinterface{Draw(stcell.Screen,x,y,w,hint)HandleEvent(evtcell.Event)boolBounds()(int,int,int,int)SetBounds(x,y,w,hint)SetFocus(fbool)IsFocused()bool}

All built-in widgets embed Base, which satisfies the bounds and focus methods automatically. Custom widgets do the same.

App is the event loop:

app,_:=tcellplus.New()app.SetRoot(myWidget)// queue thread-safe UI updates from goroutinesapp.QueueUpdate(func(){myWidget.Content="done!"})app.Run()// handles events and drains update queue

commands & keymaps

Widgets decouple key events from logic using Commands and Keymaps:

km:=tcellplus.VimKeymap()// or DefaultKeymap(), EmacsKeymap()ev,_:=screen.PollEvent()cmd:=tcellplus.Resolve(ev,km)ifcmd==tcellplus.CmdUp{// ...}

Most widgets have a Keymap field that defaults to DefaultKeymap().

widgets

widget description
Input single-line text input
Text scrollable text block, optional word wrap
Table scrollable table with header row
Box border with optional title, wraps a child widget
Flex horizontal or vertical layout container
Confirm simple yes/no confirmation dialog

focus

FocusManager handles Tab/Shift+Tab cycling and mouse-click auto-focus across a set of widgets:

fm:=tcellplus.NewFocusManager()fm.Add(searchInput)fm.Add(table)fm.Add(detailView)fm.FocusByIndex(1)// focus the table programmatically// in your root widget's HandleEvent:returnfm.HandleEvent(ev)

Widgets only process events when Focused == true. FocusManager sets and clears focus as the user navigates.

table

t:=tcellplus.NewTable([]string{"name","version"})t.Rows=[][]string{{"vim","9.1"},{"go","1.22"}}// column alignment and layoutt.ColumnWidths=[]int{20,0}t.ColAlign=[]int{tcellplus.AlignLeft,tcellplus.AlignRight}// dynamic row stylingt.RowStyleFn=func(rowint)tcell.Style{ifrow%2==0{returnzebraStyle}returntcellplus.DefaultStyle}// manual sortingt.SortBy(0,func(a,bstring)bool{returna<b})// if false, arrows move a highlight cursor; Enter commits the selectiont.SelectOnMove=falset.OnSelect=func(rowint){...}

text

t:=tcellplus.NewText("hello\nworld")t.WordWrap=truet.Align=tcellplus.AlignCenter

Scrollbars render automatically on Text and Table when content overflows.

confirm modal

c:=tcellplus.NewConfirm("install package?")c.Visible=truec.OnConfirm=func(){install()}c.OnCancel=func(){c.Visible=false}// draw as overlay in your root widgetfunc(r*Root)Draw(stcell.Screen,x,y,w,hint){r.layout.Draw(s,x,y,w,h)r.confirm.Draw(s,x,y,w,h)}

drawing helpers

tcellplus.Fill(s,x,y,w,h,' ',style)tcellplus.DrawStr(s,x,y,maxWidth,style,text)// unicode-awaretcellplus.DrawScrollbar(s,x,y,h,scroll,total)

DrawStr uses go-runewidth for correct CJK and emoji column widths.

layout

flex:=tcellplus.NewFlex(tcellplus.Horizontal).Add(sidebar,20,0).// fixed 20 columnsAdd(table,0,1)// fills remaining space

Vertical and Horizontal are the two directions. Fixed > 0 takes priority; Grow distributes remaining space by weight.

colors

iftcellplus.Has256Color(){style=style.Background(tcellplus.Color256(68))}// truecolorstyle=style.Background(tcellplus.ColorRGB(30,30,46))

examples

go run ./examples/demo # search + table
go run ./examples/pkgmgr # two-panel layout with FocusManager