Who’s ready for Bubbles v2? #667
Pinned
bashbunni
announced in
Announcements
Replies: 1 comment 1 reply
-
|
You better refactor List first :P |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Bubbles v2 is here! 🫧
We're thrilled to share Bubbles v2 with you! This release accompanies Bubble Tea v2 and Lip Gloss v2 and brings a ton of consistency, new features, and quality-of-life improvements across every component. Catch 'em all:
You can also check the Upgrade Guide for more info.
There are a lot of changes in here, but we've found upgrading pretty easy, especially with a linter. Read on for the full breakdown!
Note
When in doubt, check the examples for reference — they've all been updated for v2.
🏠 New Home
Bubbles v2 now lives at
charm.land:All sub-packages follow the same pattern:
charm.land/bubbles/v2/viewport,charm.land/bubbles/v2/list, etc.🎨 Light and Dark Styles
Some Bubbles, like
help, offer default styles for both light and dark backgrounds. Since Lip Gloss v2 removesAdaptiveColor, choosing light or dark is now a manual process. You've got a couple of options.🎩 The Best Way
Have Bubble Tea query the background color for you. This properly queries the correct inputs and outputs, and happens in lockstep with your application:
If you're using Wish you must do it this way to get the background color of the client.
🤠 The Quick Way
Use the
compatpackage in Lip Gloss. It's less recommended because it contains blocking I/O that operates independently of Bubble Tea, and when used with Wish it won't detect the client's background:👀 Or Just Pick One
This pattern applies to
help,list,textarea, andtextinput.🔑 The Init You Know and Love is Back
After experimenting with a few different forms of
Initduring the alphas, we decided the v1 signature was the right call after all.Initwas a bit too redundant for our tastes given that initialization already happens inNew:✨ The Big Highlights
Getters and Setters Everywhere
All components now use getter/setter methods instead of exported
WidthandHeightfields. This lets us do internal bookkeeping when things change, and it makes the API consistent across every Bubble:Affected:
filepicker,help,progress,table,textinput,viewport.Functional Options
Constructors now use the functional options pattern instead of positional args or separate constructor functions:
DefaultKeyMap is a Function Now
All
DefaultKeyMappackage-level variables are now functions, so you get fresh values every time:Real Cursor Support 🖱️
Both
textareaandtextinputnow support real terminal cursors! The feature is opt-in, so by default your programs will continue to use the easy-breezy virtual cursor. SetVirtualCursortofalseand useModel.Cursor()for the real deal. Check out the textarea and textinput examples to see it in action.Cleaned House 🧹
All previously deprecated symbols have been removed:
NewModelvariants — just useNewspinner.Tick()— useModel.Tick()insteadpaginator.UsePgUpPgDownKeysand friends — customizeKeyMapdirectlyfilepicker.DefaultStylesWithRenderer()— Lip Gloss is pure now, useDefaultStyles()viewport.HighPerformanceRendering— no longer neededruneutilandmemoizationpackages moved tointernal/(they were never meant for public use anyway)What's Changed: the Laundry List
🔮 Cursor
Model.Blinkrenamed toModel.IsBlinkedfor clarityModel.BlinkCmd()renamed toModel.Blink()📂 Filepicker
DefaultStylesWithRenderer()removed — Lip Gloss is pure now, so just useDefaultStyles()Model.Heightbroken intoSetHeight(int)/Height() int❓ Help
Model.Widthbroken intoSetWidth(int)/Width() intDefaultStyles(isDark bool),DefaultDarkStyles(), andDefaultLightStyles()🥕 List
DefaultStyles()andNewDefaultItemStyles()now take anisDark boolparameterStyles.FilterPromptandStyles.FilterCursorhave been consolidated intoStyles.Filter(atextinput.Styles)GlobalIndexhelper added📄 Paginator
DefaultKeyMapvariable →DefaultKeyMap()functionUsePgUpPgDownKeys,UseLeftRightKeys, etc.) removed — customizeKeyMapdirectly🌈 Progress
This one got the biggest makeover!
WithGradient/WithScaledGradient→WithColors(...color.Color)— pass 2+ colors for blendingWithSolidFill(string)→WithColors(color)— pass a single color for a solid fillWithDefaultGradient()→WithDefaultBlend()WithScaled(bool)to scale the blend to fit only the filled portionWithColorFunc(func(total, current float64) color.Color)for fully dynamic coloringWithColorProfileremoved — Bubble Tea handles this automatically nowModel.FullColorandModel.EmptyColorchanged fromstringtoimage/color.ColorModel.Widthbroken intoSetWidth(int)/Width() intModel.Updatenow returnsModelinstead oftea.Model🌀 Spinner
Tick()package-level function removed — useModel.Tick()instead⏱️ Stopwatch
NewWithInterval(d)removed — useNew(WithInterval(d))instead🔢 Table
Model.Width/Model.Heightreplaced with getter/setter methodsansi.Truncateinstead ofrunewidth.Truncate✏️ Textarea
The big change here is real cursor support — but that's opt-in, so by default your programs will keep using the virtual cursor.
DefaultKeyMapvariable →DefaultKeyMap()functionPageUp/PageDownkey bindingsModel.FocusedStyle/Model.BlurredStyle→Model.Styles.Focused/Model.Styles.BlurredStyletype renamed toStyleState; newStylesstruct groupsFocused,Blurred, andCursorModel.SetCursorrenamed toModel.SetCursorColumnModel.Cursoris nowfunc() *tea.Cursorfor real cursor supportModel.VirtualCursorbool added — set tofalsewhen using a real cursorDefaultStyles(isDark bool),DefaultDarkStyles(),DefaultLightStyles()Column(),ScrollYOffset(),ScrollPosition(),MoveToBeginning(),MoveToEnd()SetPromptFunc📜 Textinput
Most of the changes here bring
textinputto parity withtextarea, including real cursor support. Styling has been consolidated into aStylesstruct withFocusedandBlurredstates:DefaultKeyMapvariable →DefaultKeyMap()functionModel.Widthbroken intoSetWidth(int)/Width() intModel.PromptStyle→StyleState.PromptModel.TextStyle→StyleState.TextModel.PlaceholderStyle→StyleState.PlaceholderModel.CompletionStyle→StyleState.SuggestionModel.Cursoris nowfunc() *tea.Cursorfor real cursor supportModel.VirtualCursor()/SetVirtualCursor(bool)addedModel.Styles()/SetStyles(Styles)addedDefaultStyles(isDark bool),DefaultDarkStyles(),DefaultLightStyles()⏲️ Timer
NewWithInterval(timeout, interval)removed — useNew(timeout, WithInterval(interval))📦 Viewport
viewportgot a ton of love in v2. Let's dive in!Breaking changes:
New(width, height int)→New(...Option)withWithWidth/WithHeightModel.Width,Model.Height,Model.YOffsetreplaced with getter/setter methodsHighPerformanceRenderingremovedShiny new features:
You can now scroll horizontally with the left and right arrow keys, and set up a custom gutter column for things like line numbers:
Highlight parts of what's being viewed with regex:
Let viewport handle soft wrapping for you:
Or, if you need fine control, use
SetContentLineswith "virtual lines" containing\n— they're treated as soft wraps automatically.Also new:
GetContent()to retrieve contentFillHeightto pad the viewport with empty linesStyleLineFuncfor per-line stylingHighlightStyleandSelectedHighlightStylefor highlight appearance💝 That's a wrap!
Feel free to reach out, ask questions, give feedback, and let us know how it's going. We'd love to know what you think.
Part of Charm.
Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
Beta Was this translation helpful? Give feedback.
All reactions