box

package module
v3.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 9, 2026 License: MIT Imports: 9 Imported by: 0

README

Box CLI Maker

logo

Go Reference Go Go Report Card GitHub release Mentioned in Awesome Go

Box CLI Maker is a Go library for rendering highly customizable boxes in the terminal.

readme

Features

  • 9 built‑in styles (Single, Double, Round, Bold, SingleDouble, DoubleSingle, Classic, Hidden, Block)
  • Custom glyphs for all corners and edges
  • Title positions: Inside, Top, Bottom
  • Content alignment: Left, Center, Right
  • Optional content wrapping with WrapContent and WrapLimit
  • Color support with:
    • First 16 ANSI color names
    • #RGB, #RRGGBB, rgb:RRRR/GGGG/BBBB, rgba:RRRR/GGGG/BBBB/AAAA
  • Unicode and emoji support with proper width handling
  • Explicit errors from Render, plus MustRender for panic‑on‑error

Installation

go get github.com/box-cli-maker/box-cli-maker/v3

Quick Start

package main

import (
    "fmt"

    box "github.com/box-cli-maker/box-cli-maker/v3"
)

func main() {
    b := box.NewBox().
    Style(box.Single).  // single-line border
    Padding(2, 1).      // inner padding: x (horizontal), y (vertical)
    TitlePosition(box.Top).
    ContentAlign(box.Center).
    Color(box.Cyan).
    TitleColor(box.BrightYellow)

    out, err := b.Render("Box CLI Maker", "Render highly customizable boxes\n in the terminal")
    if err != nil {
        panic(err)
    }
    fmt.Println(out)
}

NewBox constructs a box with the default Single style.
Configure it via fluent methods, then call Render (or MustRender) to get the box as a string.

API Overview

Construction
b := box.NewBox() // recommended

You can clone a configured box and tweak it:

base := box.NewBox().
        Style(box.Single).
        Padding(2, 1).
        ContentAlign(box.Left)

info := base.Copy().Color(box.Green)
warn := base.Copy().Color(box.Yellow)
Styles

Select a built‑in style:

b.Style(box.Double)
Styles Showcase
box.Single

single

box.SingleDouble

double single

box.Double

double

box.DoubleSingle

double single

box.Bold

bold

box.Round

round

box.Hidden

hidden

box.Classic

classic

box.Block

block

You can override any glyph after choosing a style:

b.Style(box.Single).
  TopLeft("+").
  TopRight("+").
  BottomLeft("+").
  BottomRight("+").
  Horizontal("-").
  Vertical("|")
Titles and Alignment

Title position:

b.TitlePosition(box.Inside) // default
b.TitlePosition(box.Top)
b.TitlePosition(box.Bottom)
Title position showcase
box.Inside

single

box.Top

top

box.Bottom

bottom

Content alignment:

b.ContentAlign(box.Left) // default
b.ContentAlign(box.Center)
b.ContentAlign(box.Right)
Content Alignment showcase
box.Left

left

box.Center

center

box.Right

right

Padding
b.Padding(px, py) // horizontal (px) and vertical (py) padding
b.HPadding(px)    // horizontal only
b.VPadding(py)    // vertical only

Negative padding values are allowed to be set but cause Render to return an error.

Wrapping
b.WrapContent(true)       // enable wrapping (default width: 2/3 of terminal)
b.WrapLimit(40)           // set explicit wrap width (enables wrapping)
b.WrapContent(false)      // disable wrapping

Render returns an error if the wrap limit is negative or the terminal width cannot be determined when wrapping is enabled without a limit.

Colors

Colors can be applied to:

  • Title: TitleColor
  • Content: ContentColor
  • Border: Color

Accepted formats:

  • First 16 ANSI names:

    box.Black, box.Red, box.Green, box.Yellow, box.Blue, box.Magenta, box.Cyan, box.White and their bright variants: box.BrightBlack, box.BrightRed, box.BrightGreen, box.BrightYellow, box.BrightBlue, box.BrightMagenta, box.BrightCyan, box.BrightWhite
    (plus a few aliases like box.HiRed, box.HiBlue, etc.)

  • Hex and XParseColor formats (Supports TrueColor and 8-bit):

    • #RGB
    • #RRGGBB
    • rgb:RRRR/GGGG/BBBB
    • rgba:RRRR/GGGG/BBBB/AAAA

Example:

b.TitleColor(box.BrightYellow)
b.ContentColor("#00FF00")
b.Color("rgb:0000/ffff/0000")

Invalid colors cause Render to return an error.

Rendering
out, err := b.Render("Title", "Content")
if err != nil {
    // handle invalid style, colors, padding, wrapping, etc.
}

fmt.Println(out)

Render returns an error if:

  • The BoxStyle is invalid
  • The TitlePosition is invalid
  • The wrap limit is negative
  • Padding is negative
  • A multiline title is used with a non‑Inside title position
  • Any configured colors are invalid
  • Terminal width detection fails when needed for wrapping

For convenience:

out := b.MustRender("Title", "Content") // panics on error

Examples

The examples directory contains small, focused programs that showcase different features:

  • simple_box – minimal single box with title and content.
  • content_align – compare Left, Center, and Right content alignment.
  • content_wrap – demonstrate WrapContent / WrapLimit with long text.
  • title_positions – show Inside, Top, and Bottom title placement.
  • box_styles – render all built‑in border styles and colors.
  • custom_box – build boxes using fully custom corner/edge glyphs.
  • ansi_styles_and_links – use bold/underline/blink/strikethrough and OSC 8 hyperlinks.
  • colors_and_unicode – mix hex/ANSI colors with CJK, emoji, and wrapping.
  • ansi_art – render more decorative/"artistic" boxes.
  • shared_styles – derive multiple boxes from a shared base style with Copy.
  • ksctl – real‑world example from ksctl showing wide titles vs narrow content.
  • lolcat – rainbow color demo using custom ANSI styling helpers.
  • readme – code used to generate the screenshot at the top of this README.

Unicode, Emoji, and Width Handling

This library uses mattn/go-runewidth and github.com/charmbracelet/x/ansi to handle:

  • Wide characters (e.g., CJK)
  • Emojis and other multi‑cell glyphs
  • Stripping ANSI sequences when measuring widths

Note:

  1. Rendering quality depends on the terminal emulator and font. Some combinations may misalign visually.
  2. Indic scripts and complex text may not display correctly in most terminals.
  3. Online playgrounds and many CI environments often use basic fonts and may not render Unicode/emoji correctly; widths might be misreported.

Migration from v2

v3 is a new major version with a redesigned API.

Key changes:

  • Config struct and New(Config) have been replaced with:

    b := box.NewBox().
        Style(box.Single).
        Padding(2, 1).
        TitlePosition(box.Top).
        ContentAlign(box.Left)
    
  • String‑based fields (Type, ContentAlign, TitlePos) are now strongly typed:

    • "Single"box.Single
    • "Top"box.Top
    • "Center"box.Center
  • Colors:

    • No more interface{} colors (uint, [3]uint, etc.).
    • Use ANSI names or the documented hex/rgb formats instead.
    • Invalid colors now error at Render time.
  • Print / Println behavior can be replicated by fmt.Println(b.MustRender(...)) or your own helper.

Read more at Migration guide.

The old v2 API remains available at:

go get github.com/Delta456/box-cli-maker/v2

but is no longer actively developed.

Projects Using Box CLI Maker

Acknowledgements

Thanks to:

for inspiration, and to all contributors who have improved this library over time.

License

Licensed under MIT.

Documentation

Overview

Package box renders styled boxes around text for terminal applications.

The core type is Box, constructed with NewBox and configured via a fluent API. Boxes support multiple built‑in styles, title positions, alignment, wrapping, and ANSI/truecolor output.

Basic example:

b := box.NewBox().
	Style(box.Single).
	Padding(2, 1).
	TitlePosition(box.Top).
	ContentAlign(box.Center).
	Color(box.Cyan).
	TitleColor(box.BrightYellow).

out, err := b.Render("Box CLI Maker", "Render highly customizable boxes\n in the terminal")
if err != nil {
	log.Fatal(err)
}
fmt.Println(out)

Construction

It is recommended to create boxes using NewBox, which returns a Box with sensible defaults. The returned Box can then be configured using methods such as Style, Padding, ContentAlign, Color, TitleColor, and TitlePosition.

The zero value of Box is not intended to be used directly with Render. If you construct a Box manually (e.g. with &box.Box{} or new(box.Box)), you must fully initialize all required fields (style, padding, glyphs, colors, etc.) yourself before calling Render.

Styles

Box styles are selected with Style and the BoxStyle constants:

box.Single
box.Double
box.Round
box.Bold
box.SingleDouble
box.DoubleSingle
box.Classic
box.Hidden
box.Block

You can further customize any style by overriding the corner and edge glyphs using TopRight, TopLeft, BottomRight, BottomLeft, Horizontal, and Vertical.

Titles and alignment

Titles can be placed inside the box, on the top border, or on the bottom border using TitlePosition with the TitlePosition constants:

box.Inside
box.Top
box.Bottom

Content alignment is controlled with ContentAlign and the AlignType constants:

box.Left
box.Center
box.Right

Wrapping

WrapContent enables or disables automatic wrapping of the content. By default, when wrapping is enabled, the box width is based on two‑thirds of the terminal width. WrapLimit can be used to set an explicit maximum width.

Colors

TitleColor, ContentColor, and Color accept either one of the first 16 ANSI color name constants (e.g. box.Green, box.BrightRed) or a #RGB / #RRGGBB / rgb:RRRR/GGGG/BBBB / rgba:RRRR/GGGG/BBBB/AAAA value. Invalid colors cause Render to return an error.

Errors

Render returns an error if the style or title position is invalid, the wrap limit or padding is negative, a multiline title is used with a non‑Inside title position, any configured colors are invalid, or the terminal width cannot be determined. MustRender is a convenience wrapper that panics on error.

Copying

Copy returns a shallow copy of a Box so you can define a base style and derive variants without mutating the original:

base := box.NewBox().Style(box.Single).Padding(2, 1)
info := base.Copy().Color(box.Green)
warn := base.Copy().Color(box.Yellow)

Each Copy can then be customized and rendered independently.

Index

Constants

View Source
const (
	Black   = "Black"
	Red     = "Red"
	Green   = "Green"
	Yellow  = "Yellow"
	Blue    = "Blue"
	Magenta = "Magenta"
	Cyan    = "Cyan"
	White   = "White"

	BrightBlack   = "BrightBlack"
	HiBlack       = "HiBlack"
	BrightRed     = "BrightRed"
	HiRed         = "HiRed"
	BrightGreen   = "BrightGreen"
	HiGreen       = "HiGreen"
	BrightYellow  = "BrightYellow"
	HiYellow      = "HiYellow"
	BrightBlue    = "BrightBlue"
	HiBlue        = "HiBlue"
	BrightMagenta = "BrightMagenta"
	HiMagenta     = "HiMagenta"
	BrightCyan    = "BrightCyan"
	HiCyan        = "HiCyan"
	BrightWhite   = "BrightWhite"
	HiWhite       = "HiWhite"
)

Standard and bright ANSI color name constants usable with Color, TitleColor, and ContentColor.

Variables

This section is empty.

Functions

This section is empty.

Types

type AlignType

type AlignType string

AlignType represents the horizontal alignment of content inside the box.

const (
	// Center represents centered content alignment.
	Center AlignType = "Center"
	// Left represents left-aligned content.
	Left AlignType = "Left"
	// Right represents right-aligned content.
	Right AlignType = "Right"
)

type Box

type Box struct {
	// contains filtered or unexported fields
}

Box renders styled borders around text content.

func NewBox

func NewBox() *Box

NewBox creates a new Box with the box.Single style preset applied.

func (*Box) BottomLeft

func (b *Box) BottomLeft(glyph string) *Box

BottomLeft sets the glyph used in the lower-left corner.

func (*Box) BottomRight

func (b *Box) BottomRight(glyph string) *Box

BottomRight sets the glyph used in the lower-right corner.

func (*Box) Color

func (b *Box) Color(color string) *Box

Color sets the color used for the box border (chrome).

Accepts one of the first 16 ANSI color name constants (e.g. box.Green, box.BrightRed) or a #RGB / #RRGGBB / rgb:RRRR/GGGG/BBBB / rgba:RRRR/GGGG/BBBB/AAAA value.

Invalid colors cause Render to return an error.

func (*Box) ContentAlign

func (b *Box) ContentAlign(align AlignType) *Box

ContentAlign sets the horizontal alignment of content inside the box.

Supported values are box.Left, box.Center, and box.Right.

func (*Box) ContentColor

func (b *Box) ContentColor(color string) *Box

ContentColor sets the color used for the content text.

Accepts one of the first 16 ANSI color name constants (e.g. box.Green, box.BrightRed) or a #RGB / #RRGGBB / rgb:RRRR/GGGG/BBBB / rgba:RRRR/GGGG/BBBB/AAAA value.

Invalid colors cause Render to return an error.

func (*Box) Copy

func (b *Box) Copy() *Box

Copy returns a shallow copy of the Box so further mutations do not affect the original.

Useful for creating base styles and deriving multiple boxes from them.

func (*Box) HPadding

func (b *Box) HPadding(px int) *Box

HPadding sets horizontal padding (left and right).

func (*Box) Horizontal

func (b *Box) Horizontal(glyph string) *Box

Horizontal sets the glyph used for the horizontal edges.

func (*Box) MustRender

func (b *Box) MustRender(title, content string) string

MustRender is like Render but panics if an error occurs.

Use MustRender in examples or CLIs where failures should abort execution instead of being handled explicitly.

func (*Box) Padding

func (b *Box) Padding(px, py int) *Box

Padding sets horizontal (px) and vertical (py) inner padding.

func (*Box) Render

func (b *Box) Render(title, content string) (string, error)

Render generates the box with the given title and content.

It returns an error if:

  • the BoxStyle is invalid,
  • the TitlePosition is invalid,
  • the wrapping limit is negative,
  • padding is negative,
  • a multiline title is used with a non-Inside TitlePosition, or
  • any configured colors are invalid.

func (*Box) Style

func (b *Box) Style(box BoxStyle) *Box

Style selects one of the built-in BoxStyle presets.

Common styles include box.Single, box.Double, box.Round, box.Bold, box.SingleDouble, box.DoubleSingle, box.Classic, box.Hidden, and box.Block.

To make custom styles, call TopRight, TopLeft, BottomRight, BottomLeft, Horizontal, and Vertical after Style to override individual glyphs.

Example:

b := box.NewBox()
b.TopRight("+").TopLeft("+").BottomRight("+").BottomLeft("_").Horizontal("-").Vertical("|")

func (*Box) TitleColor

func (b *Box) TitleColor(color string) *Box

TitleColor sets the color used for the title text.

Accepts one of the first 16 ANSI color name constants (e.g. box.Green, box.BrightRed) or a #RGB / #RRGGBB / rgb:RRRR/GGGG/BBBB / rgba:RRRR/GGGG/BBBB/AAAA value.

Invalid colors cause Render to return an error.

func (*Box) TitlePosition

func (b *Box) TitlePosition(pos TitlePosition) *Box

TitlePosition sets where the title is rendered relative to the box.

Valid positions are box.Inside, box.Top, and box.Bottom.

func (*Box) TopLeft

func (b *Box) TopLeft(glyph string) *Box

TopLeft sets the glyph used in the upper-left corner.

func (*Box) TopRight

func (b *Box) TopRight(glyph string) *Box

TopRight sets the glyph used in the upper-right corner.

func (*Box) VPadding

func (b *Box) VPadding(py int) *Box

VPadding sets vertical padding (top and bottom).

func (*Box) Vertical

func (b *Box) Vertical(glyph string) *Box

Vertical sets the glyph used for the vertical edges.

func (*Box) WrapContent

func (b *Box) WrapContent(allow bool) *Box

WrapContent enables or disables automatic wrapping of content.

When enabled, content is wrapped to fit roughly two-thirds of the terminal width by default. For custom limits or non-TTY outputs, use WrapLimit instead.

func (*Box) WrapLimit

func (b *Box) WrapLimit(limit int) *Box

WrapLimit enables wrapping and sets an explicit maximum width for content.

type BoxStyle

type BoxStyle string

BoxStyle defines a built‑in border style for a Box.

const (
	// Single is a box style with single-line borders.
	Single BoxStyle = "Single"
	// Double is a box style with double-line borders.
	Double BoxStyle = "Double"
	// Round is a box style with rounded corners.
	Round BoxStyle = "Round"
	// Bold is a box style with heavy lines.
	Bold BoxStyle = "Bold"
	// SingleDouble is a box style with single horizontal and double vertical lines.
	SingleDouble BoxStyle = "SingleDouble"
	// DoubleSingle is a box style with double horizontal and single vertical lines.
	DoubleSingle BoxStyle = "DoubleSingle"
	// Classic is a box style using plus and minus characters.
	Classic BoxStyle = "Classic"
	// Hidden is a box style with invisible borders.
	Hidden BoxStyle = "Hidden"
	// Block is a box style with solid block characters.
	Block BoxStyle = "Block"
)

type TitlePosition

type TitlePosition string

TitlePosition represents the position of the title relative to the box.

const (
	// Inside places the title as the first lines inside the box.
	Inside TitlePosition = "Inside"
	// Top places the title on the top border of the box.
	Top TitlePosition = "Top"
	// Bottom places the title on the bottom border of the box.
	Bottom TitlePosition = "Bottom"
)

Directories

Path Synopsis
examples
ansi_art command
box_styles command
content_align command
content_wrap command
custom_box command
ksctl command
lolcat command
readme command
shared_styles command
simple_box command
title_positions command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL