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
examples/scripts/event_viewer.exs
# This example demonstrates handling and displaying of events.
#
# Run this with: mix run examples/without-runtime/event_viewer.exs
# Top-level setup is not needed if module handles it
# alias Raxol.{EventManager, Window}
# import Raxol.View
# Start the window and subscribe to events
# {:ok, _pid} = Window.start_link()
# {:ok, _pid} = EventManager.start_link()
# :ok = EventManager.subscribe(self())
defmodule EventViewer do
# use Raxol.View
import Raxol.View
alias Raxol.{EventManager, Window}
# Removed alias Raxol.View as import Raxol.View is used
# @line_count 30 # Unused
@title "Event Viewer (click, resize, or press a key - 'q' to quit)"
# Correct syntax for atom
@input_mode :esc_with_mouse
def start do
{:ok, _pid} = Window.start_link(input_mode: @input_mode)
{:ok, _pid} = EventManager.start_link()
:ok = EventManager.subscribe(self())
# Initial update removed, first event will render
# :ok = Window.update(layout())
loop()
end
def loop do
receive do
{:event, %{ch: ?q}} ->
:ok = EventManager.stop()
:ok = Window.close()
{:event, %{} = event} ->
:ok = Window.update(event_view(event))
loop()
end
end
def event_view(%{
type: type,
mod: mod,
key: key,
ch: ch,
w: w,
h: h,
x: x,
y: y
}) do
type_name = reverse_lookup(event_types(), type)
key_name =
if key != 0,
do: reverse_lookup(keys(), key),
else: :none
# Wrap the whole view in ~V and the panel
~V"""
<.panel title={@title} height=:fill>
<.table>
<.tr>
<.td>Type</.td>
<.td>{inspect(type)}</.td>
<.td>{inspect(type_name)}</.td>
</.tr>
<.tr>
<.td>Mod</.td>
<.td>{inspect(mod)}</.td>
<.td></.td>
</.tr>
<.tr>
<.td>Key</.td>
<.td>{inspect(key)}</.td>
<.td>{inspect(key_name)}</.td>
</.tr>
<.tr>
<.td>Char</.td>
<.td>{inspect(ch)}</.td>
<.td>{<<ch::utf8>>}</.td>
</.tr>
<.tr>
<.td>Width</.td>
<.td>{inspect(w)}</.td>
<.td></.td>
</.tr>
<.tr>
<.td>Height</.td>
<.td>{inspect(h)}</.td>
<.td></.td>
</.tr>
<.tr>
<.td>X</.td>
<.td>{inspect(x)}</.td>
<.td></.td>
</.tr>
<.tr>
<.td>Y</.td>
<.td>{inspect(y)}</.td>
<.td></.td>
</.tr>
</.table>
</.panel>
"""
end
# Removed layout function, incorporated into event_view
# def layout(children \\ []) do
# view do
# panel([title: @title, height: :fill], children)
# end
# end
def reverse_lookup(map, val) do
# Add safety for not found keys
case Enum.find(map, fn {_, v} -> v == val end) do
{key, _} -> key
nil -> :unknown
end
end
# Simplified event_types and keys maps (assuming these exist elsewhere or are for example)
# Example
defp event_types, do: %{key: 1, mouse: 2, resize: 3}
# Example
defp keys, do: %{enter: 13, q: 113}
# Removed commented out render function
# defp render(events) do
# ...
# end
# Removed unused helper
# defp key_from_val(map, val) do
# ...
# end
end
# Removed confusing top-level code
# Initial state: empty event log
# state = EventViewer.new()
# Render the initial view
# :ok = Window.update(EventViewer.render(state))
# Main loop
# loop = fn loop, state ->
# ...
# end
# Start the loop
# loop.(loop, state)
# Start the application via the module
EventViewer.start()