-
-
Save meowgorithm/1777377a43373f563476a2bcb7d89306 to your computer and use it in GitHub Desktop.
Lip Gloss Box with Label
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"strings" | |
"github.com/charmbracelet/lipgloss" | |
) | |
type BoxWithLabel struct { | |
BoxStyle lipgloss.Style | |
LabelStyle lipgloss.Style | |
} | |
func NewDefaultBoxWithLabel() BoxWithLabel { | |
return BoxWithLabel{ | |
BoxStyle: lipgloss.NewStyle(). | |
Border(lipgloss.RoundedBorder()). | |
BorderForeground(lipgloss.Color("63")). | |
Padding(1), | |
// You could, of course, also set background and foreground colors here | |
// as well. | |
LabelStyle: lipgloss.NewStyle(). | |
PaddingTop(0). | |
PaddingBottom(0). | |
PaddingLeft(1). | |
PaddingRight(1), | |
} | |
} | |
func (b BoxWithLabel) Render(label, content string, width int) string { | |
var ( | |
// Query the box style for some of its border properties so we can | |
// essentially take the top border apart and put it around the label. | |
border lipgloss.Border = b.BoxStyle.GetBorderStyle() | |
topBorderStyler func(string) string = lipgloss.NewStyle().Foreground(b.BoxStyle.GetBorderTopForeground()).Render | |
topLeft string = topBorderStyler(border.TopLeft) | |
topRight string = topBorderStyler(border.TopRight) | |
renderedLabel string = b.LabelStyle.Render(label) | |
) | |
// Render top row with the label | |
borderWidth := b.BoxStyle.GetHorizontalBorderSize() | |
cellsShort := max(0, width+borderWidth-lipgloss.Width(topLeft+topRight+renderedLabel)) | |
gap := strings.Repeat(border.Top, cellsShort) | |
top := topLeft + renderedLabel + topBorderStyler(gap) + topRight | |
// Render the rest of the box | |
bottom := b.BoxStyle.Copy(). | |
BorderTop(false). | |
Width(width). | |
Render(content) | |
// Stack the pieces | |
return top + "\n" + bottom | |
} | |
func max(a, b int) int { | |
if a > b { | |
return a | |
} | |
return b | |
} | |
func main() { | |
const body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam imperdiet ultrices felis, et condimentum odio fringilla et. Etiam porttitor volutpat diam non gravida. Donec et condimentum nulla. Sed consectetur viverra fermentum. Pellentesque eget metus ut felis faucibus consectetur nec ac mi." | |
b := NewDefaultBoxWithLabel() | |
fmt.Println(b.Render("Title", body, 40)) | |
} |
Thank you very much for this. One small update; I had to use topBorderStyler func(...string)
instead of topBorderStyler func(string)
. I think it changed in lipgloss here
Another change is to preserve box style background within the Render method.
topBorderStyler = lipgloss.NewStyle().
Foreground(b.BoxStyle.GetBorderTopForeground()).
Background(b.BoxStyle.GetBorderTopBackground()).
Render
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output: