Skip to content

Event & Callback Reference

Every widget callback has a specific payload type. This document lists all callback signatures and event struct fields so you never need to read source code to wire up handlers.


Core Types

Callback<T>

All event handlers use Callback<T>. Create them via ctx.link().callback(...):

rust
// Map event to message:
ctx.link().callback(|e: ListEvent| Msg::Select(e.index))

// Ignore event payload:
ctx.link().callback(|_| Msg::DoSomething)

// Direct message constructor (when Msg variant takes the same type):
ctx.link().callback(Msg::TextChanged)  // Msg::TextChanged(String)

KeyHandler

Used for on_key props. Created via ctx.link().key_handler(...):

rust
ctx.link().key_handler(|key: KeyEvent| {
    match key.code {
        KeyCode::Enter => Some(Msg::Submit),
        _ => None,  // None = unhandled, key bubbles
    }
})

Event Structs

ListEvent

Emitted by: List::on_select, List::on_activate, List::on_item_click

rust
pub struct ListEvent {
    pub index: usize,   // Selected/activated item index
}

CheckboxEvent

Emitted by: Checkbox::on_toggle

rust
pub struct CheckboxEvent {
    pub state: CheckboxState,  // New state after toggle
}

TabsEvent

Emitted by: Tabs::on_change, VStack::on_tab_change

rust
pub struct TabsEvent {
    pub index: usize,  // Newly active tab index
}

ScrollEvent

Emitted by: ScrollView::on_scroll (including reconcile-time sync when the controlled offset differs), TextArea::on_scroll

rust
pub struct ScrollEvent {
    pub offset: usize,           // New scroll offset (row index)
    pub metrics: ScrollMetrics,   // Viewport metrics
}

pub struct ScrollMetrics {
    pub len: usize,       // Total scrollable rows
    pub visible: usize,   // Number of visible rows
    pub max_offset: usize, // Maximum scroll offset
}

DiffScrollEvent (feature diff-view)

Emitted by: DiffView::on_scroll

rust
pub struct DiffScrollEvent {
    pub pane: DiffPane,      // Which pane emitted the event
    pub scroll: ScrollEvent, // Underlying scroll payload
}

pub enum DiffPane {
    Left,
    Right,
    Unified,
}

MouseEvent

Emitted by: Button::on_click, List::on_click, MouseRegion::on_click

rust
pub struct MouseEvent {
    pub x: u16,            // Terminal-space X
    pub y: u16,            // Terminal-space Y
    pub kind: MouseKind,   // Down, Up, Drag, ScrollUp, ScrollDown, ...
    pub mods: KeyMods,     // Modifier keys held
}

Drag And Drop Events

Emitted by: DragSource, DropTarget

rust
pub struct DragOverEvent {
    pub x: u16,            // Terminal-space X
    pub y: u16,            // Terminal-space Y
    pub local_y: u16,      // Y relative to the drop target top edge
    pub local_height: u16, // Drop target height in cells
    pub payload: Arc<dyn DragPayload>,
}

pub struct DropEvent {
    pub x: u16,            // Terminal-space X
    pub y: u16,            // Terminal-space Y
    pub local_y: u16,      // Y relative to the drop target top edge
    pub local_height: u16, // Drop target height in cells
    pub payload: Arc<dyn DragPayload>,
}

HyperlinkEvent

Emitted by: Hyperlink::on_activate

rust
pub struct HyperlinkEvent {
    pub label: Arc<str>,         // Link label
    pub href: Option<Arc<str>>,  // Optional destination URL
}

MouseMoveEvent

Emitted by: MouseRegion::on_mouse_move

rust
pub struct MouseMoveEvent {
    pub x: u16,          // Terminal-space X
    pub y: u16,          // Terminal-space Y
    pub local_x: u16,    // Relative to MouseRegion rect
    pub local_y: u16,    // Relative to MouseRegion rect
    pub target_w: u16,   // MouseRegion width
    pub target_h: u16,   // MouseRegion height
    pub mods: KeyMods,   // Modifier keys held
}

KeyEvent

Emitted by: Component::on_key, KeyHandler

rust
pub struct KeyEvent {
    pub code: KeyCode,  // Char('a'), Enter, Esc, Tab, F(1), Up, Down, ...
    pub mods: KeyMods,  // Modifier flags
}

pub struct KeyMods {
    pub ctrl: bool,
    pub alt: bool,
    pub shift: bool,
    pub super_key: bool,
}

Common pitfall: matching only key.code ignores modifiers. For example, Ctrl+S and S share the same code, so prefer key helpers that check both code and modifier state.

rust
ctx.link().key_handler(|key: KeyEvent| {
    if key.is(KeyCode::Enter) {
        Some(Msg::Submit)
    } else if key.is_with(KeyCode::Char('s'), KeyMods::CTRL) {
        Some(Msg::Save)
    } else {
        None
    }
})

TextAreaEvent

Emitted by: TextArea::on_change

rust
pub struct TextAreaEvent {
    pub value: Arc<str>,
    pub cursor: usize,
    pub anchor: Option<usize>,
}

Use TextArea::bind(&TextEditor) and TextAreaEvent::apply_to(&mut TextEditor) to keep value, cursor, and selection in sync across rerenders.

InputEvent

Emitted by: Input::on_change

rust
pub struct InputEvent {
    pub value: Arc<str>,
    pub cursor: usize,
    pub anchor: Option<usize>,
}

Use Input::bind(&TextInput) and InputEvent::apply_to(&mut TextInput) to keep value, cursor, and selection in sync across rerenders.

SentinelEvent

Emitted by: TextArea::on_sentinel_event (vector batch)

rust
pub enum SentinelEvent {
    Deleted {
        id: SentinelId,
        sentinel: TextAreaSentinel,
    },
}

TextEditEvent

Emitted by: Input::on_edit, TextArea::on_edit

rust
pub struct TextEditEvent {
    pub value: String,         // Full text value after edit
    pub kind: TextEditKind,    // Type of edit
}

pub enum TextEditKind {
    Insert,
    Delete,
    Replace,
    Paste,
    Cut,
    Undo,
    Redo,
}

ComboBoxCommitEvent

Emitted by: ComboBox::on_commit

rust
pub struct ComboBoxCommitEvent {
    pub index: Option<usize>,   // Source index (None if custom value)
    pub value: Arc<str>,         // Committed text
    pub from_custom_value: bool, // true if free-form input
}

MultiSelectToggleEvent

Emitted by: MultiSelect::on_toggle

rust
pub struct MultiSelectToggleEvent {
    pub index: usize,     // Toggled row index
    pub selected: bool,   // New selection state
}

MultiSelectChangeEvent

Emitted by: MultiSelect::on_change

rust
pub struct MultiSelectChangeEvent {
    pub selected_indices: Vec<usize>,
}

MultiSelectCommitEvent

Emitted by: MultiSelect::on_commit

rust
pub struct MultiSelectCommitEvent {
    pub selected_indices: Vec<usize>,
}

HexAreaCursorEvent

Emitted by: HexArea::on_cursor_change

rust
pub struct HexAreaCursorEvent {
    pub cursor: usize,
    pub anchor: Option<usize>,
}

HexAreaChangeEvent

Emitted by: HexArea::on_change

rust
pub struct HexAreaChangeEvent {
    pub bytes: Arc<[u8]>,
}

HexAreaEditEvent

Emitted by: HexArea::on_edit

rust
pub struct HexAreaEditEvent {
    pub index: usize,
    pub before: Option<u8>,
    pub after: Option<u8>,
    pub kind: HexAreaEditKind,
}

DraggableTabCloseEvent

Emitted by: DraggableTabBar::on_close

rust
pub struct DraggableTabCloseEvent {
    pub index: usize,  // Closed tab index
}

DraggableTabReorderEvent

Emitted by: DraggableTabBar::on_reorder

rust
pub struct DraggableTabReorderEvent {
    pub from: usize,  // Source tab index
    pub to: usize,    // Destination tab index
}

Widget Callback Summary

Quick lookup - which callbacks does each widget support?

Button

CallbackPayloadWhen
on_clickMouseEventClick or Enter on focused button
on_keyKeyHandlerAny key while focused
CallbackPayloadWhen
on_activateHyperlinkEventClick, Enter, or Space
on_keyKeyHandlerNon-activation keys while focused

Input

CallbackPayloadWhen
on_changeStringEvery keystroke (new full value)
on_editTextEditEventStructured edit events

TextArea

CallbackPayloadWhen
on_changeTextAreaEventEvery edit (value, cursor, anchor)
on_editTextEditEventStructured edit events
on_scrollScrollEventScroll offset changes
on_scroll_tousizeScrollbar interaction
on_sentinels_changeVec<TextAreaSentinel>Custom sentinel list after prune (e.g. token deleted)
on_sentinel_eventVec<SentinelEvent>Lifecycle events (e.g. Deleted with stable id + payload)
on_images_changeVec<ImageContent>Image list updated
on_image_pasteImageContentLegacy: single image pasted

List

CallbackPayloadWhen
on_selectListEventSelection changes (keyboard or mouse)
on_activateListEventEnter key (or click if activate_on_click is true)
on_item_clickListEventRow clicked with mouse
on_clickMouseEventRaw mouse click on list area
on_scroll_tousizeScrollbar interaction
on_keyKeyHandlerKey while focused

Checkbox

CallbackPayloadWhen
on_toggleCheckboxEventState toggled (keyboard or mouse)
on_clickMouseEventRaw mouse click
on_keyKeyHandlerKey while focused

Radio

CallbackPayloadWhen
on_changeusizeSelection changed (new index)

Select

CallbackPayloadWhen
on_selectusizeItem selected
on_changeusizeSelection changed
on_toggleboolDropdown opened/closed

ComboBox

CallbackPayloadWhen
on_query_changeArc<str>Input text changed
on_open_changeboolDropdown open/close requested
on_active_index_changeOption<usize>Active row changed
on_commitComboBoxCommitEventEnter/activate commit

MultiSelect

CallbackPayloadWhen
on_active_index_changeusizeActive row changed
on_toggleMultiSelectToggleEventRow toggled
on_changeMultiSelectChangeEventSelected set changed
on_commitMultiSelectCommitEventEnter pressed

Slider

CallbackPayloadWhen
on_changef64Value changed (drag or keyboard)
on_clickf64Click or Enter

DatePicker

CallbackPayloadWhen
on_select(i32, u32, u32)Day selected (year, month, day)
on_prev_month()Navigate to previous month
on_next_month()Navigate to next month

Tabs

CallbackPayloadWhen
on_changeTabsEventActive tab changed

DraggableTabBar

CallbackPayloadWhen
on_changeTabsEventActive tab changed
on_closeDraggableTabCloseEventTab close button clicked
on_reorderDraggableTabReorderEventTab dragged to new position
on_clickMouseEventRaw mouse click on tab bar

ScrollView

CallbackPayloadWhen
on_scrollScrollEventUser input / scrollbar; also after reconcile when a controlled offset differs from the laid-out offset (sync)
on_scroll_tousizeScrollbar interaction

DiffView (feature diff-view)

CallbackPayloadWhen
on_scrollDiffScrollEventA rendered diff pane scrolls

MouseRegion

CallbackPayloadWhen
on_clickMouseEventLeft-button click
on_mouse_moveMouseMoveEventPointer movement

HexArea

CallbackPayloadWhen
on_cursor_changeHexAreaCursorEventCursor movement
on_changeHexAreaChangeEventBytes modified
on_editHexAreaEditEventPer-edit metadata
on_scrollScrollEventNavigation/wheel scroll
on_keyKeyHandlerCustom key handler

Element::empty()

Use in conditional branches where no widget should be rendered:

rust
if condition {
    some_widget.into()
} else {
    Element::empty()
}

MIT OR Apache-2.0