Behaviour for reusable Tela UI components.
A component is a self-contained, pure widget: it owns its own state struct
and exposes three callbacks — init/1, handle_event/2, and view/1
— mirroring the shape of the top-level Tela behaviour. Components are
embedded in a parent model; the parent is responsible for forwarding key
events and side-effect messages to the component.
Usage
defmodule MyWidget do
use Tela.Component
@impl Tela.Component
def init(opts), do: %{value: Keyword.get(opts, :value, "")}
@impl Tela.Component
def handle_event(model, _key), do: {model, nil}
@impl Tela.Component
def view(model), do: Tela.Frame.new(model.value)
endContract
init/1
Receives a keyword list of options and returns the initial component model.
Returns a plain model — not {model, cmd}. Components do not fire
startup commands; the parent is responsible for any initial cmd (such as
starting a spinner tick via Tela.Component.Spinner.tick_cmd/1).
handle_event/2
Receives the component model and a Tela.Key struct. Returns
{new_model, cmd}. Must be a pure function.
Display-only components (such as Tela.Component.Spinner) always return
{model, nil}.
view/1
Receives the component model and returns a Tela.Frame.t(). Must be a pure
function. Compose multiple component frames with Tela.Frame.join/2 in the
parent's view/1.
Side-effect messages
Components that produce side effects (e.g. animation ticks) expose a
dedicated handler function outside the behaviour — for example,
Tela.Component.Spinner.handle_tick/2. The parent routes relevant messages
from handle_info/2 to the component's handler and merges the returned cmd.
Summary
Callbacks
Called for key events forwarded by the parent.
Called once to initialise the component. Returns the initial model.
Called by the parent's view/1 to render the component.
Callbacks
@callback handle_event(model :: term(), key :: Tela.Key.t()) :: {term(), Tela.cmd()}
Called for key events forwarded by the parent.
Returns {new_model, cmd}. Must be a pure function.
Called once to initialise the component. Returns the initial model.
Receives a keyword list of options. Returns a plain model term — not a
{model, cmd} tuple. Any startup commands (such as an initial tick) must
be launched by the parent.
@callback view(model :: term()) :: Tela.Frame.t()
Called by the parent's view/1 to render the component.
Returns a Tela.Frame.t() containing the component's rendered content and
an optional cursor position relative to the component's own top-left. Must
be a pure function.
Parents compose child frames using Tela.Frame.join/2, which adjusts
cursor row offsets automatically.