Current section

Files

Jump to
cringe lib cringe.ex
Raw

lib/cringe.ex

defmodule Cringe do
@moduledoc """
OTP-native terminal UI toolkit for Elixir.
Cringe builds terminal documents from plain Elixir data and renders them into
terminal frames. The API is intentionally small while the package is early.
"""
alias Cringe.Document.Text
alias Cringe.Widgets.{Input, Progress, Select, Spinner}
@doc """
Builds a text node.
iex> Cringe.text("hello")
%Cringe.Document.Text{content: "hello", opts: []}
"""
@spec text(IO.chardata(), keyword()) :: Text.t()
def text(content, opts \\ []), do: Text.new(content, opts)
defmacro __using__(_opts) do
quote do
import Cringe
end
end
defmacro column(first \\ [], second \\ []), do: Cringe.DSL.column_ast(first, second)
defmacro row(first \\ [], second \\ []), do: Cringe.DSL.row_ast(first, second)
defmacro box(first \\ [], second \\ []), do: Cringe.DSL.box_ast(first, second)
@doc """
Builds a render-only progress bar widget.
"""
@spec progress(keyword()) :: Cringe.Document.t()
def progress(opts \\ []), do: Progress.new(opts)
@doc """
Builds a render-only spinner widget.
"""
@spec spinner(keyword()) :: Cringe.Document.t()
def spinner(opts \\ []), do: Spinner.new(opts)
@doc """
Builds a render-only text input widget.
"""
@spec input(keyword()) :: Cringe.Document.t()
def input(opts \\ []), do: Input.new(opts)
@doc """
Builds a render-only select/list widget.
"""
@spec select(keyword()) :: Cringe.Document.t()
def select(opts \\ []), do: Select.new(opts)
@doc """
Renders a terminal document to a string.
iex> Cringe.text("hello") |> Cringe.render(width: 3)
"hel"
"""
@spec render(Cringe.Document.t(), Cringe.Renderer.render_opts()) :: String.t()
def render(document, opts \\ []), do: Cringe.Renderer.render(document, opts)
@doc """
Renders a terminal document to a frame.
"""
@spec frame(Cringe.Document.t(), Cringe.Renderer.render_opts()) :: Cringe.Frame.t()
def frame(document, opts \\ []), do: Cringe.Renderer.frame(document, opts)
@doc """
Starts a supervised Cringe runtime.
"""
@spec run(module(), keyword()) :: GenServer.on_start()
def run(app, opts \\ []), do: Cringe.Runtime.start_link(Keyword.put(opts, :app, app))
end