Raxol.LiveView.TerminalComponentLegacy (Raxol v2.0.1)

View Source

Legacy Phoenix LiveComponent for embedding terminal buffers in LiveView.

NOTE: This is the legacy implementation. New code should use Raxol.LiveView.TerminalComponent from lib/raxol/liveview/terminal_component.ex.

Provides a drop-in terminal component with event handling, theming, and performance optimizations for 60fps rendering.

Features

  • Event handling (keyboard, mouse, clipboard)
  • Multiple themes (Nord, Dracula, Solarized, Monokai)
  • Cursor rendering and styling
  • Focus management
  • Accessibility (ARIA labels, keyboard navigation)
  • Performance monitoring (logs if > 16ms)

Usage

# In your LiveView template
<.live_component
  module={Raxol.LiveView.TerminalComponent}
  id="terminal-1"
  buffer={@buffer}
  theme={:nord}
  on_keypress={&handle_terminal_input/1}
/>

Event Handling

The component can emit the following events:

  • on_keypress - Keyboard input (includes key, modifiers)
  • on_click - Mouse click (includes x, y coordinates)
  • on_paste - Clipboard paste (includes text)
  • on_focus - Terminal gained focus
  • on_blur - Terminal lost focus

Complete Example

defmodule MyAppWeb.TerminalLive do
  use MyAppWeb, :live_view
  alias Raxol.Core.{Buffer, Box}
  alias Raxol.LiveView.TerminalComponent

  def mount(_params, _session, socket) do
    buffer = Buffer.create_blank_buffer(80, 24)
    buffer = Box.draw_box(buffer, 0, 0, 80, 24, :double)
    buffer = Buffer.write_at(buffer, 2, 2, "Welcome to Raxol!", %{bold: true})

    {:ok, assign(socket,
      buffer: buffer,
      cursor_pos: {2, 4}
    )}
  end

  def render(assigns) do
    ~H"""
    <div class="terminal-container">
      <.live_component
        module={TerminalComponent}
        id="my-terminal"
        buffer={@buffer}
        theme={:dracula}
        cursor_position={@cursor_pos}
        on_keypress={fn event -> send(self(), {:keypress, event}) end}
      />
    </div>
    """
  end

  def handle_info({:keypress, %{key: key}}, socket) do
    # Handle keyboard input
    new_buffer = process_input(socket.assigns.buffer, key)
    {:noreply, assign(socket, buffer: new_buffer)}
  end
end