Packages
Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.
Current section
Files
Jump to
Current section
Files
lib/raxol/playground/demos/progress_demo.ex
defmodule Raxol.Playground.Demos.ProgressDemo do
@moduledoc "Playground demo: progress bar with value tracking."
use Raxol.Core.Runtime.Application
@bar_width 30
@max_progress 100
@manual_step 5
@auto_step 2
@auto_tick_ms 200
@info_box_width 35
@label_pad_width 8
@impl true
def init(_context) do
%{value: 50, auto: false}
end
@impl true
def update(message, model) do
case message do
key_match("+") ->
{%{model | value: min(model.value + @manual_step, @max_progress)}, []}
key_match("-") ->
{%{model | value: max(model.value - @manual_step, 0)}, []}
key_match("a") ->
{%{model | auto: not model.auto}, []}
key_match("r") ->
{%{model | value: 0}, []}
:tick when model.auto ->
new_val =
if model.value >= @max_progress, do: 0, else: model.value + @auto_step
{%{model | value: new_val}, []}
_ ->
{model, []}
end
end
@impl true
def view(model) do
filled = round(model.value / @max_progress * @bar_width)
empty = @bar_width - filled
bar = String.duplicate("#", filled) <> String.duplicate(".", empty)
auto_label = if model.auto, do: "ON", else: "OFF"
column style: %{gap: 1} do
[
text("Progress Demo", style: [:bold]),
divider(),
progress(value: model.value, max: @max_progress),
text("[#{bar}] #{model.value}%"),
divider(),
box style: %{border: :single, padding: 1, width: @info_box_width} do
column style: %{gap: 0} do
[
text("Value: #{model.value}/#{@max_progress}"),
text("Auto-increment: #{auto_label}")
]
end
end,
visual_bars(model.value),
text("[+/-] adjust [a] auto [r] reset", style: [:dim])
]
end
end
@impl true
def subscribe(model) do
if model.auto do
[subscribe_interval(@auto_tick_ms, :tick)]
else
[]
end
end
defp visual_bars(value) do
column style: %{gap: 0} do
[
bar_line("Default", value, @bar_width),
bar_line("Half", div(value, 2), @bar_width),
bar_line("Double", min(value * 2, @max_progress), @bar_width)
]
end
end
defp bar_line(label, val, width) do
filled = round(val / @max_progress * width)
empty = width - filled
bar = String.duplicate("=", filled) <> String.duplicate("-", empty)
text("#{String.pad_trailing(label, @label_pad_width)} [#{bar}] #{val}%")
end
end