479 lines · 12.9 KB

Bubbles v2 Reference

Per-component migration tables for Bubbles v2. Requires Bubble Tea v2 and Lip Gloss v2.

Table of Contents

Global Patterns

tea.KeyMsg → tea.KeyPressMsg

// v1
case tea.KeyMsg:
// v2
case tea.KeyPressMsg:

Exported Width/Height fields → getter/setter methods

// v1
m.Width = 40
m.Height = 20
fmt.Println(m.Width, m.Height)

// v2
m.SetWidth(40)
m.SetHeight(20)
fmt.Println(m.Width(), m.Height())

Affected: filepicker, help, progress, table, textinput, viewport.

DefaultKeyMap variables → functions

// v1
km := textinput.DefaultKeyMap
km.Paste.SetEnabled(false)

// v2
km := textinput.DefaultKeyMap()
km.Paste.SetEnabled(false)

Affected: paginator, textarea, textinput.

AdaptiveColor → LightDark with isDark bool

Style functions that auto-adapted now require an explicit isDark bool. See Light and Dark Styles.

Removed NewModel aliases

All NewModel variables removed. Use New directly. Affected: help, list, paginator, spinner, textinput.

Cursor

v1 v2
model.Blink model.IsBlinked
model.BlinkCmd() model.Blink()

Filepicker

v1 v2
DefaultStylesWithRenderer(r) DefaultStyles()
model.Height = 10 model.SetHeight(10)
_ = model.Height _ = model.Height()

Help

v1 v2
model.Width = 80 model.SetWidth(80)
_ = model.Width _ = model.Width()
NewModel() New()

New functions: DefaultStyles(isDark bool), DefaultDarkStyles(), DefaultLightStyles(). Apply styles explicitly:

// v1: colors auto-adapted
h := help.New()

// v2
h := help.New()
h.Styles = help.DefaultStyles(isDark)

List

v1 v2
DefaultStyles() DefaultStyles(isDark)
NewDefaultItemStyles() NewDefaultItemStyles(isDark)
styles.FilterPrompt styles.Filter.Focused.Prompt / styles.Filter.Blurred.Prompt
styles.FilterCursor styles.Filter.Cursor
NewModel(...) New(...)

Styles.FilterPrompt and Styles.FilterCursor consolidated into Styles.Filter (a textinput.Styles struct).

Paginator

v1 v2
DefaultKeyMap (var) DefaultKeyMap() (func)
model.UsePgUpPgDownKeys Removed — customize KeyMap directly
model.UseLeftRightKeys Removed — customize KeyMap directly
model.UseUpDownKeys Removed — customize KeyMap directly
model.UseHLKeys Removed — customize KeyMap directly
model.UseJKKeys Removed — customize KeyMap directly
NewModel(...) New(...)

Progress

Most extensive changes.

Width

// v1
p.Width = 40
// v2
p.SetWidth(40)
fmt.Println(p.Width())

Colors (string → image/color.Color)

// v1
p.FullColor = "#FF0000"
p.EmptyColor = "#333333"

// v2
p.FullColor = lipgloss.Color("#FF0000")
p.EmptyColor = lipgloss.Color("#333333")

Gradient/Blend options

// v1
progress.New(progress.WithGradient("#5A56E0", "#EE6FF8"))
progress.New(progress.WithDefaultGradient())
progress.New(progress.WithScaledGradient("#5A56E0", "#EE6FF8"))
progress.New(progress.WithDefaultScaledGradient())
progress.New(progress.WithSolidFill("#7571F9"))

// v2
progress.New(progress.WithColors(lipgloss.Color("#5A56E0"), lipgloss.Color("#EE6FF8")))
progress.New(progress.WithDefaultBlend())
progress.New(progress.WithColors(lipgloss.Color("#5A56E0"), lipgloss.Color("#EE6FF8")), progress.WithScaled(true))
progress.New(progress.WithDefaultBlend(), progress.WithScaled(true))
progress.New(progress.WithColors(lipgloss.Color("#7571F9")))
v1 v2
WithGradient(a, b string) WithColors(colors ...color.Color)
WithDefaultGradient() WithDefaultBlend()
WithScaledGradient(a, b string) WithColors(...) + WithScaled(true)
WithDefaultScaledGradient() WithDefaultBlend() + WithScaled(true)
WithSolidFill(string) WithColors(color) (single color)
WithColorProfile(termenv.Profile) Removed (automatic)
Update() (tea.Model, tea.Cmd) Update() (Model, tea.Cmd)

New: WithColorFunc(func(total, current float64) color.Color) for dynamic per-cell coloring; WithScaled(bool).

Spinner

v1 v2
NewModel() New()
spinner.Tick() (package func) model.Tick() (method)

Stopwatch

// v1
sw := stopwatch.NewWithInterval(500 * time.Millisecond)
// v2
sw := stopwatch.New(stopwatch.WithInterval(500 * time.Millisecond))
v1 v2
NewWithInterval(d) New(WithInterval(d))

Table

v1 v2
model.viewport.Width model.Width() / model.SetWidth(w)
model.viewport.Height model.Height() / model.SetHeight(h)

Table already had SetWidth/SetHeight/Width()/Height() in v1; internally these now use viewport getter/setters.

Textarea

KeyMap

// v1
km := textarea.DefaultKeyMap
// v2
km := textarea.DefaultKeyMap()

New key bindings: PageUp, PageDown.

Styles

// v1
ta.FocusedStyle.Base = lipgloss.NewStyle().Border(lipgloss.RoundedBorder())
ta.BlurredStyle.Base = lipgloss.NewStyle().Border(lipgloss.HiddenBorder())

// v2: styles nested under Styles struct, access via Styles.Focused / Styles.Blurred (type StyleState)
v1 v2
textarea.Style (type) textarea.StyleState (type)
model.FocusedStyle model.Styles.Focused
model.BlurredStyle model.Styles.Blurred
DefaultStyles() (focused, blurred Style) DefaultStyles(isDark bool) Styles

Cursor

// v1
ta.Cursor              // cursor.Model (virtual cursor)
ta.SetCursor(col)      // set cursor column

// v2
ta.Cursor()            // func() *tea.Cursor (real cursor)
ta.SetCursorColumn(col)
ta.VirtualCursor       // bool: true = virtual, false = real
ta.Styles.Cursor       // CursorStyle for cursor appearance

New: Column(), ScrollYOffset(), ScrollPosition(), MoveToBeginning(), MoveToEnd().

Textinput

KeyMap

// v1
km := textinput.DefaultKeyMap
// v2
km := textinput.DefaultKeyMap()

Width

// v1
ti.Width = 40
// v2
ti.SetWidth(40)

Styles

Individual style fields moved into a Styles struct:

// v1
ti.PromptStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("63"))
ti.TextStyle = lipgloss.NewStyle()
ti.PlaceholderStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
ti.CompletionStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))

// v2
s := textinput.DefaultStyles(isDark)
s.Focused.Prompt = lipgloss.NewStyle().Foreground(lipgloss.Color("63"))
s.Focused.Text = lipgloss.NewStyle()
s.Focused.Placeholder = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
s.Focused.Suggestion = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
ti.SetStyles(s)
v1 Field v2 Location
Model.PromptStyle StyleState.Prompt
Model.TextStyle StyleState.Text
Model.PlaceholderStyle StyleState.Placeholder
Model.CompletionStyle StyleState.Suggestion
Model.CursorStyle Styles.Cursor
Model.Cursor (cursor.Model) Model.Cursor() (func → *tea.Cursor)

New: Model.Styles() / Model.SetStyles(Styles); Model.VirtualCursor() / Model.SetVirtualCursor(bool).

Timer

// v1
t := timer.NewWithInterval(30*time.Second, 100*time.Millisecond)
// v2
t := timer.New(30*time.Second, timer.WithInterval(100*time.Millisecond))
v1 v2
NewWithInterval(timeout, interval) New(timeout, WithInterval(interval))

Viewport

Constructor

// v1
vp := viewport.New(80, 24)

// v2
vp := viewport.New(viewport.WithWidth(80), viewport.WithHeight(24))
// or
vp := viewport.New()
vp.SetWidth(80)
vp.SetHeight(24)

Width, Height, YOffset

// v1
vp.Width = 80
vp.Height = 24
vp.YOffset = 5

// v2
vp.SetWidth(80)
vp.SetHeight(24)
vp.SetYOffset(5)
fmt.Println(vp.Width(), vp.Height(), vp.YOffset())

Removed

HighPerformanceRendering — removed entirely.

New features (non-breaking)

  • Soft wrapping: vp.SoftWrap = true
  • Left gutter for line numbers via vp.LeftGutterFunc
  • Highlighting: SetHighlights, HighlightNext, HighlightPrevious, ClearHighlights
  • SetContentLines([]string), GetContent() string
  • FillHeight bool — fill with empty lines
  • StyleLineFunc func(int) lipgloss.Style — per-line styling
  • Horizontal scrolling (arrow keys, mouse wheel)

Light and Dark Styles

Lip Gloss v2 removes AdaptiveColor; Bubbles no longer auto-detects the terminal background. Choose light or dark explicitly.

Recommended: query via Bubble Tea

func (m model) Init() tea.Cmd { return tea.RequestBackgroundColor }

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.BackgroundColorMsg:
        isDark := msg.IsDark()
        m.help.Styles = help.DefaultStyles(isDark)
        m.list.Styles = list.DefaultStyles(isDark)
    }
    return m, nil
}

Required when using Wish to detect the client's background.

Quick: compat package

import "charm.land/lipgloss/v2/compat"

var isDark = compat.HasDarkBackground()

func main() {
    h := help.New()
    h.Styles = help.DefaultStyles(isDark)
}

Warning: compat uses blocking I/O outside Bubble Tea's event loop and will not detect remote client backgrounds over SSH.

Manual

h.Styles = help.DefaultDarkStyles()
h.Styles = help.DefaultLightStyles()

Removed Symbols Reference

Package Removed Replacement
cursor Model.Blink Model.IsBlinked
cursor Model.BlinkCmd() Model.Blink()
filepicker DefaultStylesWithRenderer(r) DefaultStyles()
filepicker Model.Height (field) SetHeight() / Height()
help NewModel New()
help Model.Width (field) SetWidth() / Width()
list NewModel New()
list DefaultStyles() DefaultStyles(isDark)
list NewDefaultItemStyles() NewDefaultItemStyles(isDark)
list Styles.FilterPrompt Styles.Filter (textinput.Styles)
list Styles.FilterCursor Styles.Filter.Cursor
paginator DefaultKeyMap (var) DefaultKeyMap() (func)
paginator NewModel New()
paginator UsePgUpPgDownKeys etc. Customize KeyMap directly
progress WithGradient(a, b) WithColors(colors...)
progress WithDefaultGradient() WithDefaultBlend()
progress WithScaledGradient(a, b) WithColors(...) + WithScaled(true)
progress WithDefaultScaledGradient() WithDefaultBlend() + WithScaled(true)
progress WithSolidFill(string) WithColors(color)
progress WithColorProfile(p) Removed (automatic)
progress Model.Width (field) SetWidth() / Width()
spinner NewModel New()
spinner Tick() (package func) Model.Tick()
stopwatch NewWithInterval(d) New(WithInterval(d))
table Model.Width (field) SetWidth() / Width()
table Model.Height (field) SetHeight() / Height()
textarea DefaultKeyMap (var) DefaultKeyMap() (func)
textarea Style (type) StyleState (type)
textarea Model.FocusedStyle Model.Styles.Focused
textarea Model.BlurredStyle Model.Styles.Blurred
textarea Model.SetCursor(col) Model.SetCursorColumn(col)
textarea DefaultStyles() DefaultStyles(isDark)
textinput DefaultKeyMap (var) DefaultKeyMap() (func)
textinput NewModel New()
textinput Model.Width (field) SetWidth() / Width()
textinput Model.PromptStyle StyleState.Prompt
textinput Model.TextStyle StyleState.Text
textinput Model.PlaceholderStyle StyleState.Placeholder
textinput Model.CompletionStyle StyleState.Suggestion
textinput Model.CursorStyle Styles.Cursor
textinput Model.Cursor (cursor.Model) Model.Cursor() (func → *tea.Cursor)
timer NewWithInterval(t, i) New(t, WithInterval(i))
viewport New(w, h int) New(...Option)
viewport Model.Width (field) SetWidth() / Width()
viewport Model.Height (field) SetHeight() / Height()
viewport Model.YOffset (field) SetYOffset() / YOffset()
viewport HighPerformanceRendering Removed
runeutil Entire package Moved to internal/runeutil (not importable)