1# Bubbles Component Catalog
2
3All components live under `charm.land/bubbles/v2/<package>`.
4
5## spinner
6
7Animated loading indicator with preset and custom frame sets.
8
9**Key Types:**
10- `Model` - component state (Spinner, Style fields)
11- `Spinner` - frame definition (`Frames []string`, `FPS time.Duration`)
12- `TickMsg` - animation frame message
13
14**Presets:** `Line`, `Dot`, `MiniDot`, `Jump`, `Pulse`, `Points`, `Globe`, `Moon`, `Monkey`, `Meter`, `Hamburger`, `Ellipsis`
15
16**Constructor:**
17```go
18s := spinner.New(spinner.WithSpinner(spinner.Dot), spinner.WithStyle(style))
19```
20
21**Start:** Return `m.spinner.Tick` from your `Init()`.
22
23**Usage:**
24```go
25m.spinner, cmd = m.spinner.Update(msg)
26view := m.spinner.View()
27```
28
29---
30
31## textinput
32
33Single-line text input with cursor, placeholder, validation, echo modes, and autocomplete suggestions.
34
35**Key Types:**
36- `Model` - component state
37- `KeyMap` - customizable keybindings
38- `EchoMode` - `EchoNormal`, `EchoPassword`, `EchoNone`
39- `ValidateFunc` - `func(string) error`
40- `Styles` - focused/blurred state styles
41
42**Constructor:**
43```go
44ti := textinput.New()
45ti.Placeholder = "Type here..."
46ti.CharLimit = 100
47ti.SetWidth(40)
48```
49
50**Key Methods:**
51- `Focus() tea.Cmd` / `Blur()` - focus management
52- `Value() string` / `SetValue(string)` - get/set content
53- `SetSuggestions([]string)` - autocomplete suggestions (set `ShowSuggestions = true`)
54- `SetStyles(Styles)` - apply styles
55- `Validate ValidateFunc` - assign validation function, errors go to `Err` field
56
57---
58
59## textarea
60
61Multi-line text editor with line numbers, word wrapping, cursor navigation, and viewport scrolling.
62
63**Key Types:**
64- `Model` - component state
65- `KeyMap` - extensive keybindings (character/word/line movement, case transforms, transpose)
66- `LineInfo` - cursor position metadata
67
68**Constructor:**
69```go
70ta := textarea.New()
71ta.SetWidth(60)
72ta.SetHeight(10)
73ta.Placeholder = "Enter text..."
74ta.ShowLineNumbers = true
75```
76
77**Key Methods:**
78- `Focus() tea.Cmd` / `Blur()` - focus management
79- `Value() string` / `SetValue(string)` - get/set content
80- `Line() int` / `LineCount() int` - cursor line info
81- `SetStyles(Styles)` - focused/blurred styles
82
83---
84
85## list
86
87Batteries-included list browser with fuzzy filtering, pagination, help, spinner, and status messages.
88
89**Key Types:**
90- `Model` - component state
91- `Item` interface - must implement `FilterValue() string`
92- `ItemDelegate` interface - `Render`, `Height`, `Spacing`, `Update` methods
93- `FilterState` - `Unfiltered`, `Filtering`, `FilterApplied`
94- `FilterFunc` - custom filter function
95- `Rank` - filter match result
96
97**Constructor:**
98```go
99items := []list.Item{myItem1, myItem2}
100l := list.New(items, myDelegate, width, height)
101l.Title = "My List"
102```
103
104**Key Methods:**
105- `SetItems([]Item)` / `Items() []Item` - manage items
106- `SelectedItem() Item` / `Index() int` - get selection
107- `SetSize(w, h int)` - resize
108- `SetFilteringEnabled(bool)` - toggle filtering
109- `NewStatusMessage(string) tea.Cmd` - show temporary status
110- `SetShowHelp(bool)` / `SetShowTitle(bool)` / `SetShowFilter(bool)` - toggle UI elements
111
112**Built-in Filter:** `list.DefaultFilter` (fuzzy), `list.UnsortedFilter`
113
114---
115
116## table
117
118Tabular data display with row selection and keyboard navigation.
119
120**Key Types:**
121- `Model` - component state
122- `Row` - `[]string`
123- `Column` - `Title string`, `Width int`
124- `KeyMap` - up/down/page/goto keybindings
125- `Styles` - `Header`, `Cell`, `Selected`
126
127**Constructor:**
128```go
129t := table.New(
130 table.WithColumns([]table.Column{
131 {Title: "Name", Width: 20},
132 {Title: "Age", Width: 5},
133 }),
134 table.WithRows([]table.Row{
135 {"Alice", "30"},
136 {"Bob", "25"},
137 }),
138 table.WithHeight(10),
139 table.WithFocused(true),
140)
141```
142
143**Key Methods:**
144- `Focus()` / `Blur()` - focus management
145- `SelectedRow() Row` / `Cursor() int` - get selection
146- `SetRows([]Row)` / `SetColumns([]Column)` - update data
147- `SetWidth(int)` / `SetHeight(int)` - resize
148- `SetCursor(int)` - set selection index
149- `FromValues(value, separator string)` - parse string data
150- `HelpView() string` - render help from keymap
151- `UpdateViewport()` - refresh after data changes
152
153---
154
155## viewport
156
157Scrollable content viewer with vertical/horizontal scrolling, soft wrap, mouse wheel, line gutters, and text highlighting.
158
159**Key Types:**
160- `Model` - component state
161- `KeyMap` - scroll keybindings (Up/Down/Left/Right/PageUp/PageDown/HalfPageUp/HalfPageDown)
162- `GutterFunc` / `GutterContext` - left gutter rendering (line numbers, etc.)
163
164**Constructor:**
165```go
166vp := viewport.New(viewport.WithWidth(80), viewport.WithHeight(24))
167vp.SetContent("long text content here...")
168```
169
170**Key Methods:**
171- `SetContent(string)` / `GetContent() string` - set/get content
172- `SetContentLines([]string)` - set content as lines
173- `SetWidth(int)` / `SetHeight(int)` - resize
174- `ScrollDown(n)` / `ScrollUp(n)` / `ScrollLeft(n)` / `ScrollRight(n)` - scroll
175- `GotoTop()` / `GotoBottom()` - jump to extremes
176- `AtTop() bool` / `AtBottom() bool` - position checks
177- `ScrollPercent() float64` - scroll progress (0-1)
178- `YOffset() int` / `SetYOffset(int)` - vertical position
179- `SetHighlights([][]int)` / `HighlightNext()` / `HighlightPrevious()` - search highlighting
180- `EnsureVisible(line, colstart, colend int)` - scroll to show position
181
182**Fields:**
183- `SoftWrap bool` - enable word wrap (disables horizontal scroll)
184- `FillHeight bool` - pad with empty lines
185- `MouseWheelEnabled bool` / `MouseWheelDelta int` - mouse config
186- `LeftGutterFunc GutterFunc` - line number gutter
187- `Style lipgloss.Style` - border/padding style
188- `HighlightStyle` / `SelectedHighlightStyle` - search match styles
189- `StyleLineFunc func(int) lipgloss.Style` - per-line styling
190
191---
192
193## paginator
194
195Pagination logic and display (dot or numeric style).
196
197**Key Types:**
198- `Model` - component state
199- `Type` - `Arabic` (1/5), `Dots` (bullet dots)
200- `KeyMap` - `PrevPage`, `NextPage`
201
202**Constructor:**
203```go
204p := paginator.New(paginator.WithPerPage(10), paginator.WithTotalPages(5))
205```
206
207**Key Methods:**
208- `NextPage()` / `PrevPage()` - navigate
209- `SetTotalPages(itemCount int) int` - calculate pages from item count
210- `GetSliceBounds(length int) (start, end int)` - get slice indices for current page
211- `ItemsOnPage(totalItems int) int` - items on current page
212- `OnFirstPage() bool` / `OnLastPage() bool` - position checks
213
214**Fields:** `Page`, `PerPage`, `TotalPages`, `ActiveDot`, `InactiveDot`, `ArabicFormat`
215
216---
217
218## progress
219
220Animated progress bar with solid, gradient, and dynamic color fills.
221
222**Key Types:**
223- `Model` - component state
224- `FrameMsg` - animation tick
225- `ColorFunc` - `func(total, current float64) color.Color`
226
227**Constructor:**
228```go
229p := progress.New(
230 progress.WithDefaultBlend(), // purple-to-pink gradient
231 progress.WithWidth(40),
232 progress.WithoutPercentage(),
233)
234// Or solid color:
235p := progress.New(progress.WithColors(lipgloss.Color("#FF0000")))
236// Or dynamic:
237p := progress.New(progress.WithColorFunc(myColorFunc))
238```
239
240**Key Methods:**
241- `SetPercent(float64) tea.Cmd` - animate to percentage (0-1), returns cmd
242- `IncrPercent(float64) tea.Cmd` / `DecrPercent(float64) tea.Cmd` - relative changes
243- `ViewAs(float64) string` - static render at given percentage (no animation)
244- `View() string` - render current animated state
245- `Percent() float64` - current target percentage
246- `IsAnimating() bool` - whether animation is in progress
247- `SetWidth(int)` / `Width() int` - resize
248- `SetSpringOptions(frequency, damping float64)` - animation physics
249
250**Fields:** `Full`, `Empty` (runes), `FullColor`, `EmptyColor`, `ShowPercentage`, `PercentFormat`, `PercentageStyle`
251
252---
253
254## help
255
256Auto-generated horizontal help view from keybindings. Supports short (single line) and full (multi-column) modes.
257
258**Key Types:**
259- `Model` - component state
260- `KeyMap` interface - `ShortHelp() []key.Binding`, `FullHelp() [][]key.Binding`
261- `Styles` - separate styles for short/full key/desc/separator
262
263**Constructor:**
264```go
265h := help.New()
266h.SetWidth(80)
267```
268
269**Usage:**
270```go
271// Pass your KeyMap implementation
272view := h.View(myKeyMap)
273
274// Or render directly
275view := h.ShortHelpView(bindings)
276view := h.FullHelpView(bindingGroups)
277```
278
279**Fields:** `ShowAll bool` (toggle short/full), `ShortSeparator`, `FullSeparator`, `Ellipsis`
280
281---
282
283## filepicker
284
285File system browser for selecting files/directories.
286
287**Key Types:**
288- `Model` - component state
289- `KeyMap` - navigation keys (Up/Down/Back/Open/Select/PageUp/PageDown/GoToTop/GoToLast)
290- `Styles` - styles for cursor, directory, file, symlink, permissions, etc.
291
292**Constructor:**
293```go
294fp := filepicker.New()
295fp.CurrentDirectory = "/home/user"
296fp.AllowedTypes = []string{".go", ".md"}
297fp.DirAllowed = false
298fp.FileAllowed = true
299fp.ShowHidden = true
300```
301
302**Key Methods:**
303- `DidSelectFile(msg tea.Msg) (bool, string)` - check if user selected a valid file
304- `DidSelectDisabledFile(msg tea.Msg) (bool, string)` - check if user tried to select a disallowed file
305
306**Fields:** `CurrentDirectory`, `AllowedTypes`, `ShowPermissions`, `ShowSize`, `ShowHidden`, `DirAllowed`, `FileAllowed`, `AutoHeight`, `Path`, `FileSelected`
307
308---
309
310## timer
311
312Countdown timer with configurable interval.
313
314**Key Types:**
315- `Model` - component state
316- `TickMsg` - periodic tick (has `Timeout bool` flag)
317- `TimeoutMsg` - sent once when timer expires
318- `StartStopMsg` - control message
319
320**Constructor:**
321```go
322t := timer.New(30*time.Second, timer.WithInterval(100*time.Millisecond))
323```
324
325**Start:** Return `m.timer.Init()` from your `Init()`.
326
327**Key Methods:**
328- `Start() tea.Cmd` / `Stop() tea.Cmd` / `Toggle() tea.Cmd` - control
329- `Running() bool` / `Timedout() bool` - state queries
330- `View() string` - renders remaining time
331
332**Fields:** `Timeout time.Duration`, `Interval time.Duration`
333
334---
335
336## stopwatch
337
338Count-up timer with start/stop/reset.
339
340**Key Types:**
341- `Model` - component state
342- `TickMsg` - periodic tick
343- `StartStopMsg` / `ResetMsg` - control messages
344
345**Constructor:**
346```go
347sw := stopwatch.New(stopwatch.WithInterval(100*time.Millisecond))
348```
349
350**Start:** Return `m.stopwatch.Init()` from your `Init()`.
351
352**Key Methods:**
353- `Start() tea.Cmd` / `Stop() tea.Cmd` / `Toggle() tea.Cmd` / `Reset() tea.Cmd` - control
354- `Running() bool` - state query
355- `Elapsed() time.Duration` - get elapsed time
356- `View() string` - renders elapsed time
357
358**Fields:** `Interval time.Duration`
359
360---
361
362## cursor
363
364Virtual cursor used internally by textinput and textarea. Supports blink, static, and hidden modes.
365
366**Key Types:**
367- `Model` - cursor state
368- `Mode` - `CursorBlink`, `CursorStatic`, `CursorHide`
369- `BlinkMsg` - blink tick
370
371**Constructor:**
372```go
373c := cursor.New()
374```
375
376**Key Methods:**
377- `Focus() tea.Cmd` / `Blur()` - focus management
378- `SetMode(Mode) tea.Cmd` - set cursor behavior
379- `Mode() Mode` - get current mode
380- `SetChar(string)` - character under cursor
381- `Blink() tea.Cmd` - start blink cycle
382
383**Fields:** `Style`, `TextStyle`, `BlinkSpeed`, `IsBlinked`
384
385---
386
387## key
388
389Non-visual utility for defining remappable keybindings with help text integration.
390
391**Key Types:**
392- `Binding` - a set of keys with optional help text
393- `BindingOpt` - functional option for NewBinding
394- `Help` - `Key string`, `Desc string`
395
396**Constructor:**
397```go
398b := key.NewBinding(
399 key.WithKeys("k", "up"),
400 key.WithHelp("up/k", "move up"),
401)
402```
403
404**Key Functions:**
405- `key.Matches(key fmt.Stringer, bindings ...Binding) bool` - check if key matches any binding
406
407**Key Methods on Binding:**
408- `Enabled() bool` / `SetEnabled(bool)` - enable/disable
409- `Keys() []string` / `SetKeys(...string)` - get/set keys
410- `Help() Help` / `SetHelp(key, desc string)` - get/set help text
411- `Unbind()` - remove all keys and help
412
413---
414
415## runeutil (internal)
416
417Internal sanitizer for cleaning rune input (tab/newline replacement). Not part of the public API.