Orange (orange v0.3.0)

Terminal UI framework for Elixir.

A framework empowering developers to build complex terminal UI applications. Orange provides a declarative way to build UI components and manage terminal events. Orange offers stateful components which can encapsulate local state and logics, allows you to split your application into discrete sub-components. For example, here is a panel displays a random numbers every 1 second:

defmodule Panel do
  @behaviour Orange.Component

  import Orange.Macro

  @impl true
  def init(_attrs), do: %{state: 0, events_subscription: true}

  @impl true
  def after_mount(_state, _attrs, update) do
    spawn_link(fn -> random_number(update) end)
  end

  defp random_number(update) do
    number = :rand.uniform(100)
    update.(number)
    Process.sleep(1000)
    random_number(update)
  end

  @impl true
  def handle_event(event, state, _attrs) do
    case event do
      %Orange.Terminal.KeyEvent{code: {:char, "q"}} ->
        Orange.stop()
        state

      _ ->
        state
    end
  end

  @impl true
  def render(state, _attrs, _update) do
    rect style: [width: 25, height: 10, border: true] do
      span do
        "Random number: #{state}"
      end
    end
  end
end

# Start the application. To quit, press 'q'.
Orange.start(Panel)

Summary

Functions

Focus a component by component_id.

Start the runtime and render the UI root.

Stop the runtime

Subscribe to the event manager.

Unfocus a component by component_id.

Unsubscribe to the event manager.

Functions

Link to this function

focus(component_id)

Focus a component by component_id.

There can be only one focused component at a time. If a component is focused, it will receive all the events and prevent other components from receiving them. This is useful when you want a component to intercept all terminal events, for example, an input.

Start the runtime and render the UI root.

The root component must be a custom component.

Stop the runtime

Link to this function

subscribe(component_id)

Subscribe to the event manager.

Subscribed components will receive terminal events. To unsubscribe, use unsubscribe/1.

Examples

defmodule Example do
  @behaviour Orange.Component

  import Orange.Macro

  @impl true
  def init(_attrs), do: %{state: nil}

  @impl true
  def after_mount(_state, _attrs, _update) do
    Orange.subscribe(:root)
  end

  @impl true
  def render(_state, _attrs, _update) do
    span do
      "Hello"
    end
  end
end

Orange.start({Example, id: :root})
Link to this function

unfocus(component_id)

Unfocus a component by component_id.

Link to this function

unsubscribe(component_id)

Unsubscribe to the event manager.