- βοΈ Utilize 340+ built-in tints. Check them all out here! We're taking advantage of the great work others have done with iTerm2-Color-Schemes, and making them more accessible in a programmatic fashion.
- βοΈ Support for dynamically changing tints at runtime, to give immediate feedback on which tints might look the best for your application and terminal setup.
- βοΈ Piecemeal support for specific tints. Really like one specific tint, and want to use that as the standard for your TUI? No problem!
- βοΈ Extendible with your own custom tints, in addition to marshalling and unmarshalling from JSON, if you wanted to support reading/writing tints to and from a file.
- βοΈ Works with
lipglossand similar tools which support thecolor.Colorinterface from stdlib!
go get -u github.com/lrstanley/bubbletint/v2@latestTake a look at all tints here.
BubbleTint supports three different modes of usage, as shown below:
package main
import (
// [...]
tint "github.com/lrstanley/bubbletint/v2"
)
func main() {
// [...]
tint.NewDefaultRegistry()
tint.SetTint(tint.TintDraculaPlus) // Set a specific tint.
tint.SetTintID("dracula_plus") // Or by ID (this aligns with a Tint's ID field).
// You can now use the current tint from the registry:
style := lipgloss.NewStyle().
SetForeground(tint.Current().Fg).
Background(tint.Current().BrightGreen)
}package main
import (
// [...]
tint "github.com/lrstanley/bubbletint/v2"
)
func main() {
// [...]
theme := tint.NewRegistry(
// Default tint.
tint.TintDraculaPlus,
// All others you want to register.
tint.TintCatppuccinFrappe,
tint.TintCatppuccinMocha,
tint.TintDraculaPlus,
tint.TintMonokaiPro,
tint.TintTinaciousDesignDark,
}
theme.Register(tint.TintNord) // Register additional tints on the custom registry.
theme.SetTint(tint.TintNord) // Can still set a tint on a custom registry.
// Can also paginate through tints, using PreviousTint/NextTint
theme.NextTint()
// You can now use the current tint from the registry:
style := lipgloss.NewStyle().
SetForeground(theme.Current().Fg).
Background(theme.Current().BrightGreen)
}package main
import (
// [...]
tint "github.com/lrstanley/bubbletint/v2"
)
var (
statusbarStyle = lipgloss.NewStyle().
SetForeground(tint.TintDraculaPlus.Fg).
Background(tint.TintDraculaPlus.BrightGreen)
)
// Or:
var (
theme = tint.TintDraculaPlus
statusbarStyle = lipgloss.NewStyle().
SetForeground(theme.Fg).
Background(theme.BrightGreen)
)... and that's it!
- Uses a static theme with a specific palette for the entire application.
- Example source
- Uses the default registry (with all tints), and has keybinds to paginate through each tint.
- Note that only a portion of this example is styled (e.g. not a full background color, which may make sense for some of the provided tints).
- Example source.
- Uses the
jsonpackage to load a tint from a file. - Unmarshalling supports both
RGBAobjects and hex strings.- Example:
{"r": 255, "g": 0, "b": 0, "a": 255}or"#ff0000" - Hex strings would be easier for end users in most cases.
- Example:
- Marshalling supports RGBA. This is to ensure that we don't lose the alpha channel
of the color when marshalling to JSON. Alpha channels default to
255with all of the default tints, but if you use custom tints, this will help keep that info. - Example source.
- Uses the
chromatintsub-package to render a code example as achroma.StyleEntries, using the specified tint. - Example source.
Caution
At a high-level, there are more breaking changes with v2 of bubbletint, than not. You will want to review the new API.
Refactored the library as a whole to support the color.Color interface directly,
without relying on lipgloss, for more agnostic usage. It should now be possible to
use it with many other libraries without pulling in lipgloss (and other associated
dependencies), though you may still need down-sampling if you're not using
bubbletea/lipgloss, to support non-true-color (or 256bit) terminals.
-
This also makes it easier to use with lipgloss v2, as less conversions need to happen now. Example:
theme := tint.TintDraculaPlus s := lipgloss.NewStyle().Foreground(theme.Fg)
-
This should make things more performant.
-
Should make hex codes more consistent (some themes from our datasources had 4 length hex colors, in addition to 7 length, but that should now be normalized as 7 length.
-
Reduces total external dependencies for the main library down to 1.
Removed the tint interface with a huge list of both global functions, as well as methods for querying colors, and have instead opted for a more straightforward struct for storing color values.
-
This has lowered the overall amount of code generated.
-
Callers of the library can still implement their own interfaces.
-
The global registry still works the same as before, so you don't have to manage passing the theme state across many different components.
-
Rather than
Registry.Blue(), you'd do one of:// Using custom registry. Done during initialization. registry := tint.NewRegistry( // Default tint. tint.TintDraculaPlus, // All others you want to register. tint.TintCatppuccinFrappe, tint.TintCatppuccinMocha, tint.TintDraculaPlus, tint.TintMonokaiPro, tint.TintTinaciousDesignDark, ) // Use it. s := lipgloss.NewStyle(). Foreground(registry.Current().BrightBlue)
// Using global registry. Done during initialization. tint.SetTint(tint.TintDraculaPlus) // Use it. s := lipgloss.NewStyle(). Foreground(tint.Current().BrightBlue)
// Pick a specific tint: theme := tint.TintDraculaPlus // Set globally somewhere. // Use it. s := lipgloss.NewStyle(). Foreground(theme.BrightBlue)
We now natively support github.com/alecthomas/chroma,
through a new sub-package, github.com/lrstanley/bubbletint/chromatint/v2. See
_examples/chromatint. This allows natively mapping bubbletint's
tints to rendered versions of various programming/markup languages.
Tints are now fully JSON serializable.
- When marshalled, they will be stored as RGBA (to not lose the alpha value, if your tints support that).
- When unmarshalled, we support both RGBA (
{"r": 255, "g": 0, "b": 0, "a": 255}), in addition to hex strings ("#ff0000"), which makes it easier for end users to add their own tints.
The code now has more resilient fallbacks, reducing the potential chance that developer-error results in a panic.
- β€οΈ Please review the Code of Conduct for guidelines on ensuring everyone has the best experience interacting with the community.
- πββοΈ Take a look at the support document on guidelines for tips on how to ask the right questions.
- π For all features/bugs/issues/questions/etc, head over here.
- β€οΈ Please review the Code of Conduct for guidelines on ensuring everyone has the best experience interacting with the community.
- π Please review the contributing doc for submitting issues/a guide on submitting pull requests and helping out.
- ποΈ For anything security related, please review this repositories security policy.
MIT License
Copyright (c) 2022 Liam Stanley <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Also located here




