lipgloss
lipgloss copied to clipboard
Add innerBorder style
By having the same color for the border and the background of the element, it gives some cool results:

For context, in a game where you can buy upgrades, you can show the user the ones that have been already bought, the ones they can buy, and the ones still locked:
I think it could be a useful addition, for example when you want to highlight something as if it was a button.
Quick testing:
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
var (
innerBorder = lipgloss.Border{
Top: "▄",
Bottom: "▀",
Left: "▐",
Right: "▌",
TopLeft: "▗",
TopRight: "▖",
BottomLeft: "▝",
BottomRight: "▘",
}
)
func main() {
fmt.Println()
color := lipgloss.Color("#00f5d4)")
testBorders := lipgloss.NewStyle().Foreground(lipgloss.Color("#333")).Background(color).BorderForeground(color)
fmt.Println(testBorders.Copy().Border(lipgloss.NormalBorder()).Render("NormalBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.RoundedBorder()).Render("RoundedBorder"))
fmt.Println(testBorders.Copy().Border(innerBorder).Render("InnerBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.ThickBorder()).Render("ThickBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.DoubleBorder()).Render("DoubleBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.HiddenBorder()).Render("HiddenBorder"))
}
This is great; thanks for the PR. My only thought here is the name, since the effect you're going for in your example could also be done with inner padding. I wonder if there's anything else that's perhaps more clear. Maybe BlockBorder?
since the effect you're going for in your example could also be done with inner padding
If I'm not mistaken, inner padding + background would create a larger border effect (notice the size of the top/bottom border):

Maybe BlockBorder?
My reasoning behind the name was that by organizing the characters differently and changing corners blocks, you would get some kind of outer border, and by using a full-width block character, you would get another effect too (fullBorder), same as for Padding(1) with a width difference, as the border would be added to Width() where Padding() is part of the Width set (IIRC):

I'm of course all open to renaming it to something else, but at least you have more context now 😊
Maybe something like HalfBlockBorder? InnerHalfBlockBorder?
The characters come from here, if needed: https://en.wikipedia.org/wiki/Box-drawing_character#Block_Elements And the Unicode standard for these characters, with their names in it: http://www.unicode.org/charts/PDF/U2580.pdf
Here's a new version of the demo, with a standardized width to easily compare them together:
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
var (
fullBorder = lipgloss.Border{
Top: "█",
Bottom: "█",
Left: "█",
Right: "█",
TopLeft: "█",
TopRight: "█",
BottomLeft: "█",
BottomRight: "█",
}
outerBorder = lipgloss.Border{
Top: "▀",
Bottom: "▄",
Left: "▌",
Right: "▐",
TopLeft: "▛",
TopRight: "▜",
BottomLeft: "▙",
BottomRight: "▟",
}
innerBorder = lipgloss.Border{
Top: "▄",
Bottom: "▀",
Left: "▐",
Right: "▌",
TopLeft: "▗",
TopRight: "▖",
BottomLeft: "▝",
BottomRight: "▘",
}
)
func main() {
fmt.Println()
color := lipgloss.Color("#00f5d4)")
testBorders := lipgloss.NewStyle().Foreground(lipgloss.Color("#333")).Background(color).BorderForeground(color).Width(15)
fmt.Println(testBorders.Copy().Border(lipgloss.NormalBorder()).Render("NormalBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.RoundedBorder()).Render("RoundedBorder"))
fmt.Println(testBorders.Copy().Border(fullBorder).Render("FullBorder"))
fmt.Println(testBorders.Copy().Border(innerBorder).Render("InnerBorder"))
fmt.Println(testBorders.Copy().Border(outerBorder).Render("OuterBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.ThickBorder()).Render("ThickBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.DoubleBorder()).Render("DoubleBorder"))
fmt.Println(testBorders.Copy().Border(lipgloss.HiddenBorder()).Render("HiddenBorder"))
fmt.Println(testBorders.Copy().Padding(1).Render("WithPadding1"))
}
Not 100% sure on this but maybe this could be called OutlineBorder? Since it acts as an outline. If the full outline border is also introduced it could be OutlineBorder and ThickOutlineBorder? Or, perhaps InnerOutlineBorder / OuterOutlineBorder / FullOutlineBorder.
Thinking about this a bit more, I think BlockBorder and InnerHalfBlockBorder and OuterHalfBlockBorder also make a lot of sense.
Love the names! I will edit my PR and add the new ones too.
Hey, I took a while to get back on it, thanks for your patience 🙇
Here are the results with the new names and variations:

What do you think? Anything else I can do? 😊
Thanks so much @VictorBersy, this looks great!