TermUI.Widgets.AlertDialog (TermUI v1.0.0)

View Source

Alert dialog widget for standardized messages and confirmations.

Alert dialog is a specialized dialog with predefined button configurations and visual icons for different message types.

Usage

AlertDialog.new(
  type: :confirm,
  title: "Delete File",
  message: "Are you sure you want to delete this file?",
  on_result: fn result -> handle_result(result) end
)

Alert Types

  • :info - Information message (i icon, OK button)
  • :success - Success message (✓ icon, OK button)
  • :warning - Warning message (⚠ icon, OK button)
  • :error - Error message (✗ icon, OK button)
  • :confirm - Confirmation dialog (? icon, Yes/No buttons)
  • :ok_cancel - OK/Cancel dialog (OK/Cancel buttons)

Keyboard Navigation

  • Tab/Shift+Tab: Move between buttons
  • Enter/Space: Activate focused button
  • Escape: Close (same as Cancel/No)
  • Y: Yes (in confirm dialogs)
  • N: No (in confirm dialogs)

Mouse Support

In raw mode, dialog buttons can be clicked with the mouse. Clicking a button produces the same result as pressing Enter on that button. Mouse events are ignored in TTY mode.

Important: For accurate mouse click detection, you must call update_area/2 with the current terminal dimensions before mouse events occur.

  • Left click on button: Activate the button

Example with Mouse Support

# In your component:
def init(_opts), do: %{alert: nil}

def update(:show_confirm, state) do
  props = AlertDialog.new(type: :confirm, title: "Confirm", message: "Proceed?")
  {:ok, alert} = AlertDialog.init(props)

  # Set terminal area for accurate mouse clicks
  alert = AlertDialog.update_area(alert, %{width: 80, height: 24})

  {%{state | alert: alert}, []}
end

def update({:alert_event, event}, state) do
  {:ok, new_alert} = AlertDialog.handle_event(event, state.alert)
  {%{state | alert: new_alert}, []}
end

def view(state) do
  if state.alert do
    area = %{width: 80, height: 24}
    {:overlay, main_content(), AlertDialog.render(state.alert, area)}
  else
    main_content()
  end
end

Summary

Functions

Gets the currently focused button.

Gets the alert type.

Hides the alert.

Creates new AlertDialog widget props.

Updates the message.

Shows the alert.

Updates the terminal area for accurate mouse click detection.

Gets whether the alert is visible.

Functions

get_focused_button(state)

@spec get_focused_button(map()) :: term()

Gets the currently focused button.

get_type(state)

@spec get_type(map()) :: atom()

Gets the alert type.

hide(state)

@spec hide(map()) :: map()

Hides the alert.

new(opts)

@spec new(keyword()) :: map()

Creates new AlertDialog widget props.

Options

  • :type - Alert type (required): :info, :success, :warning, :error, :confirm, :ok_cancel
  • :title - Dialog title (required)
  • :message - Message to display (required)
  • :on_result - Callback with result (:ok, :cancel, :yes, :no)
  • :width - Dialog width (default: 50)
  • :background_style - Style for the dialog background (default: black background)
  • :border_style - Style for the border and title (default: cyan foreground)
  • :icon_style - Style for the icon
  • :message_style - Style for the message
  • :button_style - Style for buttons
  • :focused_button_style - Style for focused button

set_message(state, message)

@spec set_message(map(), String.t()) :: map()

Updates the message.

show(state)

@spec show(map()) :: map()

Shows the alert.

update_area(state, area)

@spec update_area(map(), %{width: pos_integer(), height: pos_integer()}) :: map()

Updates the terminal area for accurate mouse click detection.

Call this when the terminal is resized or before rendering to ensure mouse clicks are detected at the correct positions.

Example

# In your app's view/1, track the area:
def view(state) do
  area = %{width: 80, height: 24}
  # Update alert with current area before rendering
  alert = AlertDialog.update_area(state.alert, area)
  {:overlay, main_content, AlertDialog.render(alert, area)}
end

visible?(state)

@spec visible?(map()) :: boolean()

Gets whether the alert is visible.