2021-03-02 02:29:00 +03:00
|
|
|
package lipgloss
|
|
|
|
|
2021-03-04 03:23:52 +03:00
|
|
|
import (
|
2021-04-02 17:05:53 +03:00
|
|
|
"github.com/lucasb-eyer/go-colorful"
|
2021-03-04 03:23:52 +03:00
|
|
|
"github.com/muesli/termenv"
|
|
|
|
)
|
2021-03-02 02:29:00 +03:00
|
|
|
|
2021-03-04 02:58:45 +03:00
|
|
|
var (
|
2021-03-18 21:52:44 +03:00
|
|
|
ColorProfile termenv.Profile = termenv.ColorProfile()
|
|
|
|
color func(string) termenv.Color = ColorProfile.Color
|
|
|
|
hasDarkBackground bool = termenv.HasDarkBackground()
|
2021-03-04 02:58:45 +03:00
|
|
|
)
|
|
|
|
|
2021-03-31 05:28:54 +03:00
|
|
|
// TerminalColor is a color intended to be rendered in the terminal. It
|
|
|
|
// satisfies the Go color.Color interface.
|
2021-03-31 05:19:38 +03:00
|
|
|
type TerminalColor interface {
|
2021-03-02 02:29:00 +03:00
|
|
|
value() string
|
2021-03-26 22:57:47 +03:00
|
|
|
color() termenv.Color
|
2021-03-31 05:28:54 +03:00
|
|
|
RGBA() (r, g, b, a uint32)
|
2021-03-02 02:29:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// NoColor is used to specify the absence of color styling. When this is active
|
|
|
|
// foreground colors will be rendered with the terminal's default text color,
|
|
|
|
// and background colors will not be drawn at all.
|
|
|
|
//
|
|
|
|
// Example usage:
|
|
|
|
//
|
2021-03-18 21:34:39 +03:00
|
|
|
// var style = someStyle.Copy().Background(lipgloss.NoColor{})
|
2021-03-02 02:29:00 +03:00
|
|
|
//
|
2021-03-18 21:34:39 +03:00
|
|
|
type NoColor struct{}
|
2021-03-02 02:29:00 +03:00
|
|
|
|
2021-03-18 21:34:39 +03:00
|
|
|
func (n NoColor) value() string {
|
2021-03-02 02:29:00 +03:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2021-03-26 22:57:47 +03:00
|
|
|
func (n NoColor) color() termenv.Color {
|
|
|
|
return color("")
|
|
|
|
}
|
|
|
|
|
2021-03-31 05:28:54 +03:00
|
|
|
// RGBA returns the RGBA value of this color. Because we have to return
|
|
|
|
// something, despite this color being the absence of color, we're returning
|
2021-04-02 17:05:53 +03:00
|
|
|
// the same value that go-colorful returns on error:
|
|
|
|
//
|
|
|
|
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
|
2021-03-31 05:28:54 +03:00
|
|
|
func (n NoColor) RGBA() (r, g, b, a uint32) {
|
2021-04-02 17:05:53 +03:00
|
|
|
return 0x0, 0x0, 0x0, 0xFFFF
|
2021-03-31 05:28:54 +03:00
|
|
|
}
|
|
|
|
|
2021-03-18 21:34:39 +03:00
|
|
|
var noColor = NoColor{}
|
|
|
|
|
2021-03-02 02:29:00 +03:00
|
|
|
// Color specifies a color by hex or ANSI value. For example:
|
|
|
|
//
|
2021-03-18 21:34:39 +03:00
|
|
|
// ansiColor := lipgloss.Color("21")
|
|
|
|
// hexColor := lipgloss.Color("#0000ff")
|
2021-03-02 02:29:00 +03:00
|
|
|
//
|
|
|
|
type Color string
|
|
|
|
|
|
|
|
func (c Color) value() string {
|
|
|
|
return string(c)
|
|
|
|
}
|
|
|
|
|
2021-03-26 22:57:47 +03:00
|
|
|
func (c Color) color() termenv.Color {
|
|
|
|
return color(string(c))
|
|
|
|
}
|
|
|
|
|
2021-04-02 17:05:53 +03:00
|
|
|
// RGBA returns the RGBA value of this color. This satisfies the Go Color
|
|
|
|
// interface. Note that on error we return black with 100% opacity, or:
|
|
|
|
//
|
|
|
|
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF
|
|
|
|
//
|
|
|
|
// This is inline with go-colorful's default behavior.
|
2021-03-31 05:28:54 +03:00
|
|
|
func (c Color) RGBA() (r, g, b, a uint32) {
|
2021-04-02 17:05:53 +03:00
|
|
|
cf, err := colorful.Hex(c.value())
|
|
|
|
if err != nil {
|
|
|
|
// If we ignore the return behavior and simply return what go-colorful
|
|
|
|
// give us for the color value we'd be returning exactly this, however
|
|
|
|
// we're being explicit here for the sake of clarity.
|
|
|
|
return colorful.Color{}.RGBA()
|
|
|
|
}
|
|
|
|
return cf.RGBA()
|
2021-03-31 05:28:54 +03:00
|
|
|
}
|
|
|
|
|
2021-03-26 17:36:23 +03:00
|
|
|
// AdaptiveColor provides color options for light and dark backgrounds. The
|
2021-03-31 05:28:54 +03:00
|
|
|
// appropriate color with be returned at runtime based on the darkness of the
|
|
|
|
// terminal background color.
|
2021-03-02 02:29:00 +03:00
|
|
|
//
|
|
|
|
// Example usage:
|
|
|
|
//
|
2021-03-18 21:34:39 +03:00
|
|
|
// color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"}
|
2021-03-02 02:29:00 +03:00
|
|
|
//
|
|
|
|
type AdaptiveColor struct {
|
|
|
|
Light string
|
|
|
|
Dark string
|
|
|
|
}
|
|
|
|
|
2021-03-31 05:28:54 +03:00
|
|
|
func (ac AdaptiveColor) value() string {
|
2021-03-02 02:29:00 +03:00
|
|
|
if hasDarkBackground {
|
2021-03-31 05:28:54 +03:00
|
|
|
return ac.Dark
|
2021-03-02 02:29:00 +03:00
|
|
|
}
|
2021-03-31 05:28:54 +03:00
|
|
|
return ac.Light
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ac AdaptiveColor) color() termenv.Color {
|
|
|
|
return color(ac.value())
|
2021-03-02 02:29:00 +03:00
|
|
|
}
|
2021-03-26 22:57:47 +03:00
|
|
|
|
2021-04-02 17:05:53 +03:00
|
|
|
// RGBA returns the RGBA value of this color. This satisfies the Go Color
|
|
|
|
// interface. Note that on error we return black with 100% opacity, or:
|
|
|
|
//
|
|
|
|
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF
|
|
|
|
//
|
|
|
|
// This is inline with go-colorful's default behavior.
|
2021-03-31 05:28:54 +03:00
|
|
|
func (ac AdaptiveColor) RGBA() (r, g, b, a uint32) {
|
2021-04-02 17:05:53 +03:00
|
|
|
cf, err := colorful.Hex(ac.value())
|
|
|
|
if err != nil {
|
|
|
|
return colorful.Color{}.RGBA()
|
|
|
|
}
|
|
|
|
return cf.RGBA()
|
2021-03-26 22:57:47 +03:00
|
|
|
}
|