Composable ANSI text styles for terminal UIs.
Tela.Style provides a pure, pipe-friendly API for building and applying
ANSI styling to strings. Styles are represented as plain structs — no
processes, no I/O — and applied via render/2.
Usage
iex> Tela.Style.new() |> Tela.Style.bold() |> Tela.Style.foreground(:cyan) |> Tela.Style.render("hello")
"[1m[36mhello[0m"Styles are reusable and composable:
base = Tela.Style.new() |> Tela.Style.bold()
error = base |> Tela.Style.foreground(:red)
info = base |> Tela.Style.foreground(:cyan)
Tela.Style.render(error, "Something went wrong")
Tela.Style.render(info, "All good")Colours
Named colour atoms map to standard ANSI palette slots. The actual colour displayed depends on the terminal's colour scheme — Tela does not hardcode RGB values. This means styled Tela apps automatically respect the user's terminal theme.
Available colours: :black, :red, :green, :yellow, :blue,
:magenta, :cyan, :white, :bright_black, :bright_red,
:bright_green, :bright_yellow, :bright_blue, :bright_magenta,
:bright_cyan, :bright_white, :default.
Reverse video
reverse/1 swaps the terminal's foreground and background colours (\e[7m).
This is the standard way to render a cursor block — the result automatically
adapts to the user's terminal colour scheme.
Borders
Border styles: :none, :single, :double, :rounded, :thick.
Multi-line strings
render/2 supports multi-line strings (containing \n). Lines are
normalised to equal width before padding and borders are applied, ensuring
rectangular output. Attributes and colours are applied per-line with a
\e[0m reset at the end of each line to prevent colour bleeding.
Measuring visible width
Use width/1 to measure the visible width of a string, stripping any ANSI
escape codes before counting. Useful for layout calculations in view/1.
Summary
Functions
Sets the background colour.
Enables bold text.
Sets the border style.
Sets the background colour applied to border characters.
Sets the foreground colour applied to border characters.
Enables dim (faint) text.
Sets the foreground (text) colour.
Enables italic text.
Returns a new Tela.Style with all fields unset (nil).
Sets equal padding on all four sides.
Sets vertical (top/bottom) and horizontal (left/right) padding.
Sets padding explicitly: top, right, bottom, left.
Applies the style to a string and returns the styled string.
Enables reverse video — swaps the terminal foreground and background colours.
Enables strikethrough text.
Enables underlined text.
Returns the visible width of a string, stripping ANSI escape codes.
Types
@type border_style() :: :none | :single | :double | :rounded | :thick
A border drawing style.
@type color() ::
:black
| :red
| :green
| :yellow
| :blue
| :magenta
| :cyan
| :white
| :bright_black
| :bright_red
| :bright_green
| :bright_yellow
| :bright_blue
| :bright_magenta
| :bright_cyan
| :bright_white
| :default
A named terminal colour.
Maps to a standard ANSI palette slot. The rendered colour depends on the terminal emulator's colour scheme.
@type t() :: %Tela.Style{ background: color() | nil, bold: boolean() | nil, border: border_style() | nil, border_bg: color() | nil, border_fg: color() | nil, dim: boolean() | nil, foreground: color() | nil, italic: boolean() | nil, padding: {non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()} | nil, reverse: boolean() | nil, strikethrough: boolean() | nil, underline: boolean() | nil }
A style struct. Build with new/0 and the pipe-friendly setter functions.
Functions
Sets the background colour.
Raises ArgumentError if colour is not a known colour atom.
Examples
iex> Tela.Style.new() |> Tela.Style.background(:blue)
%Tela.Style{background: :blue}
Enables bold text.
@spec border(t(), border_style()) :: t()
Sets the border style.
Raises ArgumentError if border_style is not a known border atom.
Examples
iex> Tela.Style.new() |> Tela.Style.border(:single)
%Tela.Style{border: :single}
Sets the background colour applied to border characters.
Raises ArgumentError if colour is not a known colour atom.
Sets the foreground colour applied to border characters.
Raises ArgumentError if colour is not a known colour atom.
Enables dim (faint) text.
Sets the foreground (text) colour.
Raises ArgumentError if colour is not a known colour atom.
Examples
iex> Tela.Style.new() |> Tela.Style.foreground(:red)
%Tela.Style{foreground: :red}
Enables italic text.
@spec new() :: t()
Returns a new Tela.Style with all fields unset (nil).
Examples
iex> Tela.Style.new()
%Tela.Style{}
@spec padding(t(), non_neg_integer()) :: t()
Sets equal padding on all four sides.
@spec padding(t(), non_neg_integer(), non_neg_integer()) :: t()
Sets vertical (top/bottom) and horizontal (left/right) padding.
@spec padding( t(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer() ) :: t()
Sets padding explicitly: top, right, bottom, left.
Applies the style to a string and returns the styled string.
Supports multi-line strings (containing \n). Lines are normalised to
equal width before padding and borders are applied. Text attributes and
colours are applied per-line with a reset at the end of each line.
Examples
iex> Tela.Style.new() |> Tela.Style.bold() |> Tela.Style.render("hello")
"[1mhello[0m"
iex> Tela.Style.new() |> Tela.Style.render("plain")
"plain"
Enables reverse video — swaps the terminal foreground and background colours.
The rendered character appears as a filled block in the terminal's foreground
colour. Useful for cursor rendering: Style.new() |> Style.reverse() produces
a solid block that respects the user's terminal colour scheme.
Enables strikethrough text.
Enables underlined text.
@spec width(String.t()) :: non_neg_integer()
Returns the visible width of a string, stripping ANSI escape codes.
For multi-line strings, returns the width of the widest line.
Examples
iex> Tela.Style.width("hello")
5
iex> Tela.Style.width("[1mhello[0m")
5
iex> Tela.Style.width("hi\nworld")
5