Events from interactive widgets (buttons, inputs, sliders, etc.).
Built-in widget event families decode to atoms. Custom widget
events decode to {widget_type, event} tuples, for example
{:star_rating, :selected}.
The scope field contains the ancestor scope chain in reverse order
(nearest parent first). Use Plushie.Event.target/1 to reconstruct the
full forward-order scoped path.
The window_id field identifies which window produced the event. Runtime-
delivered widget events always include it. This stays separate from scope:
scope is container ancestry inside a window, while window_id identifies
the window itself.
Pattern matching
def update(model, %WidgetEvent{type: :click, id: "save"}), do: save(model)
def update(model, %WidgetEvent{type: :input, id: "name", value: val}), do: ...
def update(model, %WidgetEvent{type: :toggle, id: "dark", value: on?}), do: ...
# Match on scope for disambiguation
def update(model, %WidgetEvent{type: :click, id: "save", scope: ["form" | _]}), do: ...
Summary
Types
@type builtin_event_type() ::
:click
| :input
| :submit
| :toggle
| :select
| :slide
| :slide_release
| :paste
| :open
| :close
| :option_hovered
| :key_binding
| :sort
| :pane_focus_cycle
| :press
| :release
| :move
| :scroll
| :scrolled
| :enter
| :exit
| :double_click
| :resize
| :focused
| :blurred
| :drag
| :drag_end
| :key_press
| :key_release
| :pane_resized
| :pane_dragged
| :pane_clicked
| :transition_complete
@type delivered_t() :: %Plushie.Event.WidgetEvent{ data: map() | nil, id: String.t(), scope: [String.t()], type: event_type(), value: term(), window_id: String.t() }
Widget event delivered by the renderer.
@type event_type() :: builtin_event_type() | widget_event_type()
@type t() :: %Plushie.Event.WidgetEvent{ data: map() | nil, id: String.t(), scope: [String.t()], type: event_type(), value: term(), window_id: String.t() | nil }
Widget event struct.
Hand-built test events may leave window_id unset. Events decoded from the
renderer always include it.