blipgloss
Style definitions for nice terminal layouts. Powered by lipgloss and bun:ffi
.
Install
bun add blipgloss
Usage
Blipgloss takes an expressive, declarative approach to terminal rendering. Users familiar with CSS will feel at home with Blipgloss.
import { NewStyle } from 'blipgloss'
const style = NewStyle()
.Bold(true)
.Foreground("#FAFAFA")
.Background("#7D56F4")
.PaddingTop(2)
.PaddingLeft(4)
.Width(22)
console.log(style.Render("Hello, bun."))
Colors
Blipgloss supports the following color profiles:
ANSI 16 colors (4-bit)
Background("5")
Background("9")
Background("12")
ANSI 256 colors (8-bit)
Background("86")
Background("201")
Background("202")
True Color (16,777,216 colors; 24-bit)
Background("#0000FF")
Background("#04B575")
Background("#3C3C3C")
...as well as a 1-bit Ascii profile, which is black and white only.
The terminal's color profile will be automatically detected, and colors outside the gamut of the current palette will be automatically coerced to their closest available value.
Adaptive Colors
You can also specify color options for light and dark backgrounds:
Background({
Light: '236',
Dark: '248'
})
Complete Colors
CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color profiles.
Background({
True: "#0000FF",
ANSI256: "86",
ANSI: "5"
})
Complete Adaptive Colors
You can use CompleteColor with AdaptiveColor to specify the exact values for light and dark backgrounds without automatic color degradation.
Background({
Light: {TrueColor: "#d7ffae", ANSI256: "193", ANSI: "11"},
Dark: {TrueColor: "#d75fee", ANSI256: "163", ANSI: "5"}
})
The terminal's background color will automatically be detected and the appropriate color will be chosen at runtime.
Inline Formatting
Blipgloss supports the usual ANSI text formatting options:
const style = NewStyle()
.Bold(true)
.Italic(true)
.Faint(true)
.Blink(true)
.Strikethrough(true)
.Underline(true)
.Reverse(true)
Block-Level Formatting
Blipgloss also supports rules for block-level formatting:
const style = NewStyle()
.PaddingTop(2)
.PaddingRight(4)
.PaddingBottom(2)
.PaddingLeft(4)
const style = NewStyle()
.MarginTop(2)
.MarginRight(4)
.MarginBottom(2)
.MarginLeft(4)
There is also shorthand syntax for margins and padding, which follows the same format as CSS:
NewStyle().Padding(2)
NewStyle().Margin(2, 4)
NewStyle().Padding(1, 4, 2)
NewStyle().Margin(2, 4, 3, 1)
Aligning Text
You can align paragraphs of text to the left, right, or center.
import { Position } from 'blipgloss'
const style = NewStyle()
.Width(24)
.Align(Position.Left)
.Align(Position.Right)
.Align(Position.Center)
Width and Height
Setting a minimum width and height is simple and straightforward.
const str = NewStyle()
.Width(24)
.Height(32)
.Foreground("63")
.Render("What’s for lunch?")
Borders
Adding borders is easy:
import { NewStyle, Border } from 'blipgloss'
const style = NewStyle()
.BorderStyle(Border.Normal)
.BorderForeground("63")
const anotherStyle = NewStyle()
.BorderStyle(Border.Rounded)
.BorderForeground("228")
.BorderBackground("63")
.BorderTop(true).
.BorderLeft(true)
const style = NewStyle()
.BorderStyle({
Top: "._.:*:",
Bottom: "._.:*:",
Left: "|*",
Right: "|*",
TopLeft: "*",
TopRight: "*",
BottomLeft: "*",
BottomRight: "*",
})
Copying Styles
Just use Copy()
:
const style = NewStyle().Foreground("219")
const wildStyle = style.Copy().Blink(true)
Copy()
performs a copy on the underlying data structure ensuring that you get a true, dereferenced copy of a style. Without copying it's possible to mutate styles.
Unsetting Rules
All rules can be unset:
const style = NewStyle().
Bold(true).
UnsetBold().
Background("227").
UnsetBackground()
Enforcing Rules
Sometimes, such as when developing a component, you want to make sure style definitions respect their intended purpose in the UI. This is where Inline
and MaxWidth
, and MaxHeight
come in:
someStyle.Inline(true).Render("yadda yadda")
someStyle.Inline(true).MaxWidth(5).Render("yadda yadda")
someStyle.MaxWidth(5).MaxHeight(5).Render("yadda yadda")
Rendering
Generally, you just call the Render(string)
method:
console.log(NewStyle().Bold(true).Render("Hello, bun."))
Utilities
In addition to pure styling, Lip Gloss also ships with some utilities to help assemble your layouts.
Joining Paragraphs
Horizontally and vertically joining paragraphs is a cinch.
import { Position, JoinHorizontal, JoinVertical } from 'blipgloss'
JoinHorizontal(Position.Bottom, paragraphA, paragraphB, paragraphC)
JoinVertical(Position.Center, paragraphA, paragraphB)
JoinHorizontal(0.2, paragraphA, paragraphB, paragraphC)
Measuring Width and Height
Sometimes you’ll want to know the width and height of text blocks when building your layouts.
import { NewStyle, Width, Height } from 'blipgloss'
const block = NewStyle()
.Width(40)
.Padding(2)
.Render(someLongString)
const width = Width(block)
const height = Height(block)
Placing Text in Whitespace
Sometimes you’ll simply want to place a block of text in whitespace.
import { PlaceHorizontal, PlaceVertical, Place, Position } from 'blipgloss'
const block = PlaceHorizontal(80, Position.Center, fancyStyledParagraph)
const block = PlaceVertical(30, Position.Bottom, fancyStyledParagraph)
const block = Place(30, 80, Position.Right, Position.Bottom, fancyStyledParagraph)
License
MIT