TermUI.FocusManager (TermUI v0.2.0)

View Source

Central focus management for TermUI components.

The FocusManager tracks which component receives keyboard input, provides focus traversal (Tab/Shift+Tab), and manages focus trapping for modal contexts.

Usage

# Get current focus
{:ok, component_id} = FocusManager.get_focused()

# Set focus to component
:ok = FocusManager.set_focused(:my_input)

# Tab navigation
:ok = FocusManager.focus_next()
:ok = FocusManager.focus_prev()

# Focus trapping for modals
:ok = FocusManager.trap_focus(:modal_group)
:ok = FocusManager.release_focus()

Focus Stack

The FocusManager maintains a focus stack for modal contexts. When a modal opens, it pushes the current focus and sets new focus. When closed, focus pops back to the previous component.

Summary

Functions

Returns a specification to start this module under a supervisor.

Clears the current focus.

Moves focus to the next focusable component in tab order.

Moves focus to the previous focusable component in tab order.

Checks if a component is currently focused.

Gets the currently focused component.

Gets all registered focus groups.

Gets the current focus stack.

Pops focus from stack, restoring previous focus.

Pushes current focus to stack and sets new focus.

Registers a focus group for focus trapping.

Releases the current focus trap.

Requests auto-focus for a component on mount.

Sets focus to a specific component.

Starts the focus manager.

Traps focus within a group.

Unregisters a focus group.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear_focus()

@spec clear_focus() :: :ok

Clears the current focus.

focus_next()

@spec focus_next() :: :ok | {:error, atom()}

Moves focus to the next focusable component in tab order.

Returns

  • :ok - Focus moved to next component
  • {:error, :no_focusable} - No focusable components available

focus_prev()

@spec focus_prev() :: :ok | {:error, atom()}

Moves focus to the previous focusable component in tab order.

Returns

  • :ok - Focus moved to previous component
  • {:error, :no_focusable} - No focusable components available

focused?(component_id)

@spec focused?(term()) :: boolean()

Checks if a component is currently focused.

get_focused()

@spec get_focused() :: {:ok, term() | nil}

Gets the currently focused component.

Returns

  • {:ok, component_id} - The focused component
  • {:ok, nil} - No component focused

get_groups()

@spec get_groups() :: %{required(term()) => [term()]}

Gets all registered focus groups.

get_stack()

@spec get_stack() :: [term()]

Gets the current focus stack.

pop_focus()

@spec pop_focus() :: :ok | {:error, atom()}

Pops focus from stack, restoring previous focus.

Returns

  • :ok - Focus restored
  • {:error, :empty_stack} - No focus to restore

push_focus(component_id)

@spec push_focus(term()) :: :ok | {:error, atom()}

Pushes current focus to stack and sets new focus.

Useful for modal dialogs that need to restore focus when closed.

Parameters

  • component_id - Component to focus

register_group(group_id, component_ids)

@spec register_group(term(), [term()]) :: :ok

Registers a focus group for focus trapping.

Parameters

  • group_id - Unique identifier for the group
  • component_ids - List of component ids in the group

release_focus()

@spec release_focus() :: :ok

Releases the current focus trap.

request_auto_focus(component_id)

@spec request_auto_focus(term()) :: :ok

Requests auto-focus for a component on mount.

Should be called from component mount if auto_focus prop is true.

set_focused(component_id)

@spec set_focused(term() | nil) :: :ok | {:error, atom()}

Sets focus to a specific component.

Sends blur event to the previously focused component and focus event to the new component.

Parameters

  • component_id - Component to focus, or nil to clear focus

Returns

  • :ok - Focus changed successfully
  • {:error, :not_focusable} - Component cannot receive focus
  • {:error, :not_found} - Component not registered

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the focus manager.

trap_focus(group_id)

@spec trap_focus(term()) :: :ok | {:error, atom()}

Traps focus within a group.

Tab navigation will cycle within the group instead of escaping to other components.

Parameters

  • group_id - Group to trap focus within

unregister_group(group_id)

@spec unregister_group(term()) :: :ok

Unregisters a focus group.