Content-sized#
Short labels measure their own width instead of filling a column.
labels := []string{"New", "99+", "Published"}
variants := []components.BadgeVariant{
components.BadgeDefault, components.BadgeSecondary, components.BadgeOutline,
}
x := bounds.X
for index, label := range labels {
width, height := components.BadgeExtent(canvas, theme, label)
badge := ui.Rect{X: x, Width: width, Height: height}
components.PaintBadge(canvas, theme, badge, label, variants[index])
x += width + 12
}Six variants#
Default, secondary, destructive, outline, ghost and link presentations.
labels := []string{"Default", "Secondary", "Destructive", "Outline", "Ghost", "Link"}
variants := []components.BadgeVariant{
components.BadgeDefault, components.BadgeSecondary, components.BadgeDestructive,
components.BadgeOutline, components.BadgeGhost, components.BadgeLink,
}
x := bounds.X
for index, label := range labels {
width, height := components.BadgeExtent(canvas, theme, label)
badge := ui.Rect{X: x, Width: width, Height: height}
components.PaintBadge(canvas, theme, badge, label, variants[index])
x += width + 12
}Long labels#
Mixed Chinese and English labels wrap to the next row when needed.
// BadgeExtent keeps each badge as wide as its label, so a grid can wrap them.
labels := []string{"In review", "This is a long status label", "Viva native component · Published"}
variants := []components.BadgeVariant{
components.BadgeSecondary, components.BadgeOutline, components.BadgeDefault,
}
x := bounds.X
for index, label := range labels {
width, height := components.BadgeExtent(canvas, theme, label)
badge := ui.Rect{X: x, Width: width, Height: height}
components.PaintBadge(canvas, theme, badge, label, variants[index])
x += width + 12
}Installation
Copy the recipe into your own project.
go run ./cmd/viva add --out ./components/local badgeContent-sized by default#
PaintBadge measures its text and returns the resulting bounds. Supply an origin rather than stretching the badge across a container.
- Use Default for emphasis, Secondary for quieter status, Outline for low emphasis and Destructive for a failure state.
- The long-label example includes mixed Chinese and Latin text; system font metrics may differ between platforms.
Semantics#
A badge is a label, not a button. It does not accept focus or create a click target. Use a button when the element performs an action.
Keyboard
Use Tab to move between controls and Ctrl/⌘ K to search the catalog. Inside a preview, the Go runtime handles keyboard input.