# `Tela.Style`
[🔗](https://github.com/idabmat/tela/blob/v0.1.0/lib/tela/style.ex#L1)

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`.

# `border_style`

```elixir
@type border_style() :: :none | :single | :double | :rounded | :thick
```

A border drawing style.

# `color`

```elixir
@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.

# `t`

```elixir
@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.

# `background`

```elixir
@spec background(t(), color()) :: t()
```

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}

# `bold`

```elixir
@spec bold(t()) :: t()
```

Enables bold text.

# `border`

```elixir
@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}

# `border_background`

```elixir
@spec border_background(t(), color()) :: t()
```

Sets the background colour applied to border characters.

Raises `ArgumentError` if `colour` is not a known colour atom.

# `border_foreground`

```elixir
@spec border_foreground(t(), color()) :: t()
```

Sets the foreground colour applied to border characters.

Raises `ArgumentError` if `colour` is not a known colour atom.

# `dim`

```elixir
@spec dim(t()) :: t()
```

Enables dim (faint) text.

# `foreground`

```elixir
@spec foreground(t(), color()) :: t()
```

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}

# `italic`

```elixir
@spec italic(t()) :: t()
```

Enables italic text.

# `new`

```elixir
@spec new() :: t()
```

Returns a new `Tela.Style` with all fields unset (`nil`).

## Examples

    iex> Tela.Style.new()
    %Tela.Style{}

# `padding`

```elixir
@spec padding(t(), non_neg_integer()) :: t()
```

Sets equal padding on all four sides.

# `padding`

```elixir
@spec padding(t(), non_neg_integer(), non_neg_integer()) :: t()
```

Sets vertical (top/bottom) and horizontal (left/right) padding.

# `padding`

```elixir
@spec padding(
  t(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) :: t()
```

Sets padding explicitly: top, right, bottom, left.

# `render`

```elixir
@spec render(t(), String.t()) :: String.t()
```

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"

# `reverse`

```elixir
@spec reverse(t()) :: t()
```

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.

# `strikethrough`

```elixir
@spec strikethrough(t()) :: t()
```

Enables strikethrough text.

# `underline`

```elixir
@spec underline(t()) :: t()
```

Enables underlined text.

# `width`

```elixir
@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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
