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(...):
// 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(...):
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
pub struct ListEvent {
pub index: usize, // Selected/activated item index
}CheckboxEvent
Emitted by: Checkbox::on_toggle
pub struct CheckboxEvent {
pub state: CheckboxState, // New state after toggle
}TabsEvent
Emitted by: Tabs::on_change, VStack::on_tab_change
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
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
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
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
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
pub struct HyperlinkEvent {
pub label: Arc<str>, // Link label
pub href: Option<Arc<str>>, // Optional destination URL
}MouseMoveEvent
Emitted by: MouseRegion::on_mouse_move
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
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.
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
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
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)
pub enum SentinelEvent {
Deleted {
id: SentinelId,
sentinel: TextAreaSentinel,
},
}TextEditEvent
Emitted by: Input::on_edit, TextArea::on_edit
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
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
pub struct MultiSelectToggleEvent {
pub index: usize, // Toggled row index
pub selected: bool, // New selection state
}MultiSelectChangeEvent
Emitted by: MultiSelect::on_change
pub struct MultiSelectChangeEvent {
pub selected_indices: Vec<usize>,
}MultiSelectCommitEvent
Emitted by: MultiSelect::on_commit
pub struct MultiSelectCommitEvent {
pub selected_indices: Vec<usize>,
}HexAreaCursorEvent
Emitted by: HexArea::on_cursor_change
pub struct HexAreaCursorEvent {
pub cursor: usize,
pub anchor: Option<usize>,
}HexAreaChangeEvent
Emitted by: HexArea::on_change
pub struct HexAreaChangeEvent {
pub bytes: Arc<[u8]>,
}HexAreaEditEvent
Emitted by: HexArea::on_edit
pub struct HexAreaEditEvent {
pub index: usize,
pub before: Option<u8>,
pub after: Option<u8>,
pub kind: HexAreaEditKind,
}DraggableTabCloseEvent
Emitted by: DraggableTabBar::on_close
pub struct DraggableTabCloseEvent {
pub index: usize, // Closed tab index
}DraggableTabReorderEvent
Emitted by: DraggableTabBar::on_reorder
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
| Callback | Payload | When |
|---|---|---|
on_click | MouseEvent | Click or Enter on focused button |
on_key | KeyHandler | Any key while focused |
Hyperlink
| Callback | Payload | When |
|---|---|---|
on_activate | HyperlinkEvent | Click, Enter, or Space |
on_key | KeyHandler | Non-activation keys while focused |
Input
| Callback | Payload | When |
|---|---|---|
on_change | String | Every keystroke (new full value) |
on_edit | TextEditEvent | Structured edit events |
TextArea
| Callback | Payload | When |
|---|---|---|
on_change | TextAreaEvent | Every edit (value, cursor, anchor) |
on_edit | TextEditEvent | Structured edit events |
on_scroll | ScrollEvent | Scroll offset changes |
on_scroll_to | usize | Scrollbar interaction |
on_sentinels_change | Vec<TextAreaSentinel> | Custom sentinel list after prune (e.g. token deleted) |
on_sentinel_event | Vec<SentinelEvent> | Lifecycle events (e.g. Deleted with stable id + payload) |
on_images_change | Vec<ImageContent> | Image list updated |
on_image_paste | ImageContent | Legacy: single image pasted |
List
| Callback | Payload | When |
|---|---|---|
on_select | ListEvent | Selection changes (keyboard or mouse) |
on_activate | ListEvent | Enter key (or click if activate_on_click is true) |
on_item_click | ListEvent | Row clicked with mouse |
on_click | MouseEvent | Raw mouse click on list area |
on_scroll_to | usize | Scrollbar interaction |
on_key | KeyHandler | Key while focused |
Checkbox
| Callback | Payload | When |
|---|---|---|
on_toggle | CheckboxEvent | State toggled (keyboard or mouse) |
on_click | MouseEvent | Raw mouse click |
on_key | KeyHandler | Key while focused |
Radio
| Callback | Payload | When |
|---|---|---|
on_change | usize | Selection changed (new index) |
Select
| Callback | Payload | When |
|---|---|---|
on_select | usize | Item selected |
on_change | usize | Selection changed |
on_toggle | bool | Dropdown opened/closed |
ComboBox
| Callback | Payload | When |
|---|---|---|
on_query_change | Arc<str> | Input text changed |
on_open_change | bool | Dropdown open/close requested |
on_active_index_change | Option<usize> | Active row changed |
on_commit | ComboBoxCommitEvent | Enter/activate commit |
MultiSelect
| Callback | Payload | When |
|---|---|---|
on_active_index_change | usize | Active row changed |
on_toggle | MultiSelectToggleEvent | Row toggled |
on_change | MultiSelectChangeEvent | Selected set changed |
on_commit | MultiSelectCommitEvent | Enter pressed |
Slider
| Callback | Payload | When |
|---|---|---|
on_change | f64 | Value changed (drag or keyboard) |
on_click | f64 | Click or Enter |
DatePicker
| Callback | Payload | When |
|---|---|---|
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
| Callback | Payload | When |
|---|---|---|
on_change | TabsEvent | Active tab changed |
DraggableTabBar
| Callback | Payload | When |
|---|---|---|
on_change | TabsEvent | Active tab changed |
on_close | DraggableTabCloseEvent | Tab close button clicked |
on_reorder | DraggableTabReorderEvent | Tab dragged to new position |
on_click | MouseEvent | Raw mouse click on tab bar |
ScrollView
| Callback | Payload | When |
|---|---|---|
on_scroll | ScrollEvent | User input / scrollbar; also after reconcile when a controlled offset differs from the laid-out offset (sync) |
on_scroll_to | usize | Scrollbar interaction |
DiffView (feature diff-view)
| Callback | Payload | When |
|---|---|---|
on_scroll | DiffScrollEvent | A rendered diff pane scrolls |
MouseRegion
| Callback | Payload | When |
|---|---|---|
on_click | MouseEvent | Left-button click |
on_mouse_move | MouseMoveEvent | Pointer movement |
HexArea
| Callback | Payload | When |
|---|---|---|
on_cursor_change | HexAreaCursorEvent | Cursor movement |
on_change | HexAreaChangeEvent | Bytes modified |
on_edit | HexAreaEditEvent | Per-edit metadata |
on_scroll | ScrollEvent | Navigation/wheel scroll |
on_key | KeyHandler | Custom key handler |
Element::empty()
Use in conditional branches where no widget should be rendered:
if condition {
some_widget.into()
} else {
Element::empty()
}