Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,37 @@ lipgloss.NewStyle().
lipgloss.NewStyle().
Border(lipgloss.DoubleBorder(), true, false, false, true)
```
It is also possible to set and style a border title
```go

// create bold italic title horizontally aligned
// to center of the border
titleStyle := lipgloss.NewStyle().
Background(lipgloss.Color("#6124DF")).
Align(lipgloss.Center).
Bold(true).
Italic(true)

// dialog box style with its title styled
dialogBoxStyle := lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("#874BFD")).
BorderTitleStyle(titleStyle).
Padding(1, 0).
BorderTop(true).
BorderLeft(true).
BorderRight(true).
BorderBottom(true)


// Use the title with the dialog box style
dialog := lipgloss.Place(width, 9,
lipgloss.Center, lipgloss.Center,
dialogBoxStyle.Copy().BorderTitle(" Question ").Render(ui),
lipgloss.WithWhitespaceChars("猫咪"),
lipgloss.WithWhitespaceForeground(subtle),
)
```

For more on borders see [the docs][docs].

Expand Down
39 changes: 37 additions & 2 deletions borders.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,45 @@ func (s Style) applyBorder(str string) string {
border.BottomLeft = getFirstRuneAsString(border.BottomLeft)

var out strings.Builder
const sideCount = 2

// Render top
if hasTop {
top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
top = styleBorder(top, topFG, topBG)
top := ""

// sanitize title style
titleStyle := s.GetBorderTitleStyle().Copy().MaxWidth(width)

// set default padding if one is not set
if titleStyle.GetHorizontalPadding() == 0 {
titleStyle = titleStyle.Padding(0, 1)
}

title := s.GetBorderTitle()

if len(strings.TrimSpace(title)) > 0 {
titleLen := titleStyle.GetHorizontalFrameSize() + len(title)
topBeforeTitle := border.TopLeft
topAfterTitle := border.TopRight
switch titleStyle.GetAlignHorizontal() {
case Right:
topBeforeTitle = border.TopLeft + strings.Repeat(border.Top, max(0, width-1-titleLen))
case Center:
noTitleLen := width - 1 - titleLen
noTitleLen2 := noTitleLen / sideCount
topBeforeTitle = border.TopLeft + strings.Repeat(border.Top, max(0, noTitleLen2))
topAfterTitle = strings.Repeat(border.Top, max(0, noTitleLen-noTitleLen2)) + border.TopRight
case Left:
topAfterTitle = strings.Repeat(border.Top, max(0, width-1-titleLen)) + border.TopRight
}

top = styleBorder(topBeforeTitle, topFG, topBG) +
titleStyle.Render(title) +
styleBorder(topAfterTitle, topFG, topBG)
} else {
top = renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
top = styleBorder(top, topFG, topBG)
}
out.WriteString(top)
out.WriteRune('\n')
}
Expand Down Expand Up @@ -362,6 +396,7 @@ func renderHorizontalEdge(left, middle, right string, width int) string {

out := strings.Builder{}
out.WriteString(left)

for i := leftWidth + rightWidth; i < width+rightWidth; {
out.WriteRune(runes[j])
j++
Expand Down
10 changes: 9 additions & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,17 @@ var (

// Dialog.

dialogTitleStyle = lipgloss.NewStyle().
Background(lipgloss.Color("#6124DF")).
Align(lipgloss.Center).
Bold(true).
Italic(true).
Padding(0, 5)

dialogBoxStyle = lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("#874BFD")).
BorderTitleStyle(dialogTitleStyle).
Padding(1, 0).
BorderTop(true).
BorderLeft(true).
Expand Down Expand Up @@ -239,7 +247,7 @@ func main() {

dialog := lipgloss.Place(width, 9,
lipgloss.Center, lipgloss.Center,
dialogBoxStyle.Render(ui),
dialogBoxStyle.Copy().BorderTitle("Question").Render(ui),
lipgloss.WithWhitespaceChars("猫咪"),
lipgloss.WithWhitespaceForeground(subtle),
)
Expand Down
32 changes: 31 additions & 1 deletion get.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,24 @@ func (s Style) getAsInt(k propKey) int {
return 0
}

func (s Style) getAsString(k propKey) string {
if v, ok := s.rules[k]; ok {
if s, ok := v.(string); ok {
return s
}
}
return ""
}

func (s Style) getAsStyle(k propKey) Style {
if v, ok := s.rules[k]; ok {
if s, ok := v.(Style); ok {
return s
}
}
return NewStyle()
}

func (s Style) getAsPosition(k propKey) Position {
v, ok := s.rules[k]
if !ok {
Expand All @@ -456,7 +474,19 @@ func (s Style) getBorderStyle() Border {
return noBorder
}

// Split a string into lines, additionally returning the size of the widest
// GetBorderTitleStyle returns border title style if set,
// otherwise returns empty style.
func (s Style) GetBorderTitleStyle() Style {
return s.getAsStyle(borderTitleStyleKey)
}

// GetBorderTitle returns border title if set,
// otherwise returns empty string.
func (s Style) GetBorderTitle() string {
return s.getAsString(borderTitleKey)
}

// Split a string into lines, additionally returning the size of the widest.
// line.
func getLines(s string) (lines []string, widest int) {
lines = strings.Split(s, "\n")
Expand Down
12 changes: 12 additions & 0 deletions set.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,18 @@ func (s Style) BorderLeftBackground(c TerminalColor) Style {
return s
}

// BorderTitleStyle set border title style
func (s Style) BorderTitleStyle(style Style) Style {
s.set(borderTitleStyleKey, style)
return s
}

// BorderTitle set border title
func (s Style) BorderTitle(title string) Style {
s.set(borderTitleKey, title)
return s
}

// Inline makes rendering output one line and disables the rendering of
// margins, padding and borders. This is useful when you need a style to apply
// only to font rendering and don't want it to change any physical dimensions.
Expand Down
4 changes: 4 additions & 0 deletions style.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ const (
borderBottomBackgroundKey
borderLeftBackgroundKey

// Border title.
borderTitleStyleKey
borderTitleKey

inlineKey
maxWidthKey
maxHeightKey
Expand Down