Skip to main content

Border

layout.Border wraps a single child component with a configurable box border and an optional title stamped into the top rule.

Basic usage

panel := layout.NewBorder(innerComponent).
WithTitle("My Panel")

Builder options

MethodDescription
WithTitle(title string, anchor ...oat.Anchor)Set a title and optionally its horizontal position
WithTitleStyle(s latte.Style)Style applied to the title text only
WithStyle(s latte.Style)Style applied to the border itself (colour, border type, padding)
WithRoundedCorner(bool)Explicitly enable or disable arc corners (╭╮╰╯)

WithTitle

WithTitle accepts an optional oat.Anchor that controls where the title is placed in the top rule. The anchor is optional; omitting it defaults to oat.AnchorLeft.

// Left-aligned (default)
layout.NewBorder(inner).WithTitle("My Panel")

// Centred
layout.NewBorder(inner).WithTitle("My Panel", oat.AnchorCenter)

// Right-aligned
layout.NewBorder(inner).WithTitle("My Panel", oat.AnchorRight)
AnchorResult
oat.AnchorLeft (default)╭─ My Panel ──────────╮
oat.AnchorCenter╭──── My Panel ────────╮
oat.AnchorRight╭────────── My Panel ──╮

WithRoundedCorner

func (b *Border) WithRoundedCorner(rounded bool) *Border

Stores the rounded-corner intent in an internal field; does not mutate Style.Border. The effective corner shape is resolved at render time: BorderSingleBorderRounded is toggled based on this field.

// Arc corners: ╭─ My Panel ──╮ / ╰──────────╯
panel := layout.NewBorder(inner).
WithTitle("My Panel").
WithRoundedCorner(true)
Border styleWithRoundedCorner(true)
BorderSingle (default)Renders with arc corners ╭╮╰╯
BorderRoundedAlready rounded — no change
BorderDoubleSilently ignored
BorderThickSilently ignored
BorderDashedSilently ignored

Once called, this explicit choice overrides the theme's RoundedCorner setting for this Border. Calling WithRoundedCorner(false) explicitly opts out of rounded corners even when theme.RoundedCorner is true.

tip

All built-in themes have RoundedCorner: true, so Border automatically uses arc corners when a theme is applied. Only call WithRoundedCorner explicitly when you want to override the theme's default for a specific panel.

Focus highlight

When any descendant of the border is focused, Border automatically promotes its border colour to the theme's FocusBorder token. No extra code is needed.

Custom style

// Explicit padding inside the border
panel := layout.NewBorder(inner).
WithStyle(latte.Style{Padding: latte.Insets{Bottom: 1}}).
WithTitle("Editor")

// Custom border colour
panel := layout.NewBorder(inner).
WithStyle(latte.Style{BorderFG: latte.Hex("#ff6600")})

Nesting with ScrollView

When combining Border with ScrollView, prefer Border(ScrollView(VBox)) over ScrollView(Border(VBox)). In the correct pattern the border chrome is fixed and only the content scrolls. In the reverse pattern the entire Border (including its title row) scrolls off-screen.

// CORRECT — fixed border, scrolling content:
panel := layout.NewBorder(
layout.NewVBox(items...).AsScrollView().WithScrollBar(true),
).WithTitle("Items")

See ScrollView for details.