Skip to content

Releases: charmbracelet/bubbles

v0.15.0

20 Jan 16:27
4a71cee
Compare
Choose a tag to compare

Ceci, Cela

This is primarily a housekeeping release with lots and lots of bugfixes and improvements from the community. Thanks, everyone, for all your support! πŸ€—

Please do feel free to say hello, ask questions, and tell us what else you want to see in our Discord. πŸ’¬

New

  • textinput + textarea: support for forthcoming bracketed paste (see also charmbracelet/bubbletea#397) and avoid ctrl chars in clipboard input by @knz in #214
  • textinput: support key bindings textarea by @knz in #270
  • paginator: make paginator keybindings customizable by @knz in #272
  • viewport: Expose TotalLineCount() and VisibleLineCount() methods within viewport by @adaam2 in #283
  • table: make UpdateViewport() have constant runtime by @pja237 in #284
  • table: add SetColumns method to set columns by @maaslalani in #260
  • table: expose rows by @marcantoineg in #287

Fixed

New Contributors

Full Changelog: v0.14.0...v0.15.0


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Discord.

v0.14.0

06 Sep 16:34
Compare
Choose a tag to compare

Table Bubble

This feature release of Bubbles includes a brand new table bubble that you can use to show and select tabular data! Huge thanks to @wesleimp for contributing this change ❀️.

Table Bubble showing countries and their populations

See the example code for an example of how to use the table in your Bubble Tea applications.

Getting Started

Create a new table:

t := table.New(
	table.WithColumns(columns),
	table.WithRows(rows),
	table.WithFocused(true),
	table.WithHeight(7),
)

Alternatively,

t := table.New(table.WithColumns(columns))
t.SetRows(rows)
t.Focus()
t.SetHeight(7)

Style the table how you want:

s := table.DefaultStyles()
s.Header = s.Header.
	BorderStyle(lipgloss.NormalBorder()).
	BorderForeground(lipgloss.Color("240")).
	BorderBottom(true).
	Bold(false)
s.Selected = s.Selected.
	Foreground(lipgloss.Color("229")).
	Background(lipgloss.Color("57")).
	Bold(false)
t.SetStyles(s)

And then Update and Render (View) the table:

type model struct {
	table table.Model
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	var cmd tea.Cmd
	m.table, cmd = m.table.Update(msg)
	return m, cmd
}

func (m model) View() string {
	return m.table.View()
}

Other Changes

  • Ctrl+H backspaces text by @maaslalani in #199
  • LineCount() + Include New Line characters in Length() by @maaslalani in #204
  • fix(viewport): honor width and height settings by @meowgorithm in #216
  • feat(textarea): new bindings for "go to begin" / "go to end" by @knz in #226
  • feat(textarea): PromptFunc, support dynamic prompts by @knz in #211
  • fix(viewport): properly truncate to size by @knz in #228

New Contributors

Full Changelog: v0.13.0...v0.14.0

Read more about it in our examples and docs:


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.13.0

05 Jul 20:18
Compare
Choose a tag to compare

Textarea Bubble

This feature release includes a brand new textarea bubble that you can use to input as many lines of text as your heart desires (or until your computer memory runs out, whichever comes first).

Text Area Example

See the example code for a simple example of how to use the textarea in your Bubble Tea applications.

Customization

There are a few ways to customize the text area.

  • SetHeight(height int): tells the component how many lines of text it should display at once.
  • SetWidth(width int): tells the component how wide the it should be.
  • ShowLineNumbers: whether or not to show line numbers on the left-hand side of a line of text.
  • Prompt: the prompt to display on the left-hand side.
  • EndOfBufferCharacter: the character to display as the line number after the last line to fill the rest of the height. Defaults to ~.
  • CharLimit: Prevents users from typing more than a set number of characters.
  • KeyMap: The set of keybindings to navigate and interact with the textarea.

Styling

Split Editors Example

The textarea can be customized heavily with Lip Gloss.

  • FocusedStyles: the styles to be applied while the textarea is focused.
  • BlurredStyles: the styles to be applied while the textarea is focused.

Each of the above properties has the below sub-properties that can be modified.

Base             lipgloss.Style
CursorLine       lipgloss.Style
CursorLineNumber lipgloss.Style
EndOfBuffer      lipgloss.Style
LineNumber       lipgloss.Style
Placeholder      lipgloss.Style
Prompt           lipgloss.Style
Text             lipgloss.Style

See the split editors example for how to style the textarea component.

Read more about it in our examples and docs:


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.12.0

27 Jun 20:05
42f85b4
Compare
Choose a tag to compare

Validate Your Darlings

This release of Bubbles allows you to handle input validation by defining validation functions that ensure the user is typing text that you expect.

The Validate API introduces a function that is called every time the input changes to ensure that it is still valid input.

// ValidateFunc is a function that returns an error if the input is invalid.
type ValidateFunc func(string) error

// Validate is a function that checks whether or not the text within the
// input is valid. If it is not valid, the `Err` field will be set to the
// error returned by the function. If the function is not defined, all
// input is considered valid.
Validate ValidateFunc

View the Example Code to see Validate and ValidateFuncs work in code.

With these awesome changes introduced by @IllusionMan1212, we can now build forms that ensure all input is valid like a credit card input form!

Credit Card Input Demo

See the full example to handle input validation in your Bubble Tea apps.

Custom List Status Bar Item Names

Thanks to @wesleimp, lists now have a new function to allow you to set a custom status bar item name. Simply call SetStatusBarItemName on your list with the singular and plural name of your list item and Bubbles will handle the rest (defaults to "item", "items").

list.SetStatusBarItemName("grocery", "groceries")

This will change the string displayed underneath the Title of the list, in this case the item name is being used for displaying 2 groceries.

image

New Spinners πŸ’«

This release contains two brand new spinners introduced by @wesleimp, check them out:


What's Changed

New Contributors

Full Changelog: v0.11.0...v0.12.0


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Slack.

v0.11.0

02 Jun 01:34
7959eb4
Compare
Choose a tag to compare

Housekeeping

🧹 Hot on the heels of Bubble Tea v0.21.0, this is a maintenance release with a lot of great quality-of-life features from both the Charm team and the community. Enjoy!

Changelog

New

Fixed

  • list: fix padding in titlebar when nothing is displayed by @toadle in #139
  • textinput: support KeySpace in present and future Bubble Tea versions by @meowgorithm in #161

Changed

New Contributors

Full Changelog: v0.10.3...v0.11.0


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.10.3

16 Feb 15:48
Compare
Choose a tag to compare

A Couple ’o List Bugfixes

This small patch release fixes a couple small bugs with regard to the quit keybinding in list. Cheers! 🍻

Fixed

  • Properly set quit keybinding in keybinding update phase #108
  • Disable quit keybinding while filtering (thanks @lorenries!) #118

New Contributors

Full Changelog: v0.10.2...v0.10.3


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.10.2

20 Jan 18:50
Compare
Choose a tag to compare

Housekeeping

🧹 This is a small release to improve the overall integrity of the viewport and textinput Bubbles.

  • Setting the width and height on a viewport’s style attribute is now a no-op. Previously it would produce some pretty confusing rendering and generally conflict with the Width and Height attributes on the model.
  • Fix a textinput regression where deleting words left of the cursor didn't actually do anything (courtesy @IllusionMan1212)

Full Changelog: v0.10.1...v0.10.2


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.10.1

19 Jan 18:10
Compare
Choose a tag to compare

Viewport Hotfixes

This release fixes some viewport bugs introduced in v0.10.0:

  • Fixed a bug where the viewport's y-offset could be negative
  • Fixed an off-by-one error in GotoBottom()

πŸ€— Special thanks to @knipferrc and @IllusionMan1212 for their assistance with the bugfixes.

Also

Full Changelog: v0.10.0...v0.10.1


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.10.0

13 Jan 19:26
465a66e
Compare
Choose a tag to compare

Timer, stopwatch, bugfixes and quality-of-life improvements

🎊 Happy New Year! This is a big release with a couple new components, a bunch of bug fixes, and some general quality-of-life improvements across the board.

tl;dr

New

  • Add timer component (thanks @caarlos0) #67
  • Add stopwatch component (thanks @caarlos0) #68
  • viewport can now be initialized with a New() constructor at the package level #92
  • viewport now has customizable keybindings via the key package #92
  • viewport mouse wheel speed can be customized #92
  • The mouse's scroll wheel can now be disabled for a viewport #92

Changed

  • NewModel() constructors are now deprecated in favor of New() #93
  • Expose list.FilterMachesMsg (thanks @jon4hz) #77
  • Expand key.Matches to accept multiple binding arguments #84
  • spinner now ignores messages sent by other spinners #91

Fixed

  • Update keybindings when calling SetItems on a list (thanks @paralin) #90
  • Update keybindings after calling InsertItem on a list #94
  • Fix textinput infinite loop and panic (thanks @IllusionMan1212) #89
  • Fix bug where viewport wasn't rendering final lines #74
  • Fix bug where viewport performance rendering could render one line too many #74

Hungry for more? Here are the details.

New: Timer

@caarlos0 added a simple timer Bubble for counting down.

Timer example

See the example code and docs for details.

New: Stopwatch

To match the timer, @caarlos0 also added a simple stopwatch Bubble for counting up.

Timer example

See the example code and docs for details.

Constructor Changes

Prior to this update the convention was to create new models via a NewModel. We've changed that convention to New() for brevity and readability. NewModel() will continue to work in a deprecated fashion to ease the update process.

// Old
s := spinner.NewModel()

// New!
s := spinner.New()

Viewport Improvements

As of this update you're strongly encouraged to initialize viewport models with the new New(width, height int) Model function, however it's currently optional to reduce friction when upgrading.

const width, height = 40, 80
vp := viewport.New(width, height)

Viewport models also now have a Style lipgloss.Style property you can use to apply borders, margins, and padding directly to a viewport. Not more magic numbers, random constants, and fussy arithmetic.

vp.Style = lipgloss.NewStyle().
        BorderStyle(lipgloss.RoundedBorder()).
        BorderForeground(lipgloss.Color("62")).
        PaddingRight(2)

Keybindings on a viewport are now defined via the key Bubble and can now be easily remapped.

vp.KeyMap.Up = key.NewBinding(WithKeys("up", "w"))

For details see the available bindings. Note that you can also just match on keys in the parent Update and call viewport methods like LineUp programmatically.

And, lastly, you can now change the mouse wheel scroll speed, or disable it entirely:

vp := viewport.New()
vp.MouseWheelDelta = 5 // make mouse scrolling really fast!
vp.MouseWheelEnabled = false // jk, turn it off

See the viewport docs for details.

Spinner Improvements

Now spinners only respond to their own spin messages so you don't need any more fancy logic when you want to control multiple spinners at once. To start a specific spinner you now call Tick() on the model instead of the package:

s := spinner.New()

// Old
cmd := spinner.Tick()

// New
cmd := s.Tick()

For posterity, you can still use the package-level Tick method in a deprecated fashion, however note that it will affect all spinners that process the resulting TickMsg as it did prior to the release.

For details see the spinner docs.

Keybindings

key.Binding currently allows you to bind against multiple keys:

binding := key.Binding(key.WithKeys("q", "ctrl+c"))

However, sometimes you may also want to match on multiple bindings:

left := key.Binding(key.WithKeys("h", "left"))
right := key.Binding(key.WithKeys("l", "right"))

case key.Matches(msg, left), key.Matches(msg, right):

This update expands key.Matches to accept multiple arguments so you can condense the above case statement to:

case key.Matches(msg, left, right):

For more on how keybindings work see the key docs.


New Contributors

Full Changelog: v0.9.0...v0.10.0


The Charm logo

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or on Slack.

v0.9.0

08 Sep 14:40
Compare
Choose a tag to compare

Lists, Animated Progress Bar and More

There are a handful of new things in this release, the biggest being the brand new List Bubble we extrapolated from Glow. Read on!

New: List

List Example

The List Bubble is a highly customizable, batteries-included component for browsing a set of items. It features pagination, fuzzy filtering, auto-generated help, an activity spinner, and status messages, all of which can be enabled and disabled as needed.

New: Key

A non-visual component for managing keybindings. It’s useful for allowing users to remap keybindings, allows keys to be enabled and disabled programatically, and can be used to generate help views.

import "github.com/charmbracelet/bubbles/key"

up := key.NewBinding(
    key.WithKeys("up", "k"),
    key.WithHelp("↑/k", "move up"),
)

if key.Matches(msg, up) {
    // ...
}

New: Help

Help Example

A customizable horizontal mini help view that automatically generates itself from your keybindings. It features single and multi-line modes, which the user can optionally toggle between. It will truncate gracefully if the terminal is too wide for the content.

Updated: Progress Bar

The progress bar has been updated so that it can now animate itself via Harmonica. You can, of course, still render non-animated progress bars too.

Note that there are also some minor API changes to the Progress Bubble. See the changelog below.

Progress Bar Changelog

Changed

  • NewModel no longer returns an error
  • Model.View(float64) string is now Model.View() string (to render a static view per the prior version use Model.ViewAs(float64) string)
  • Invalid hex colors now render as black

New

  • Added WithSpringOptions to customize spring animation
  • Added Model.Update for animating the progress bar
  • Added Model.ViewAs(float64) string for rendering static progress bars
  • Model now satisfies the tea.Model interface making more composable

Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter or The Fediverse.

The Charm logo