Behaviour for stateful event-owning components.
See guides/event_model.md for the model. In short:
- Stateless components are plain functions:
(assigns) -> render_tree. They have no event horizon — events fired inside their subtree resolve to the nearest stateful ancestor. - Stateful components implement
Dala.Event.Component. They own events fired in their subtree and may escalate semantic events to their parent.
This is the Dala equivalent of Phoenix.LiveComponent.
Status
This is the interface declaration. The runtime that hosts these components — registering them in render trees, routing events to them, managing their lifecycle — is implemented incrementally:
- Existing
Dala.Ui.NativeView(a sibling concept for native_view widgets) remains the runtime for components that pair with custom native views. Dala.Event.Component(this module) is the event-routing abstraction: a stateful owner of events for a subtree of standard widgets.- The two will likely merge once the new event model is plumbed end-to-end.
Until then, the Bridge module handles the legacy event shapes and the
existing Dala.Ui.NativeView is the canonical stateful component.
Callbacks
defmodule MyApp.CheckoutForm do
use Dala.Event.Component
def mount(props, state), do: {:ok, Map.put(state, :email, "")}
def render(state) do
# return a render tree (uses Dala.Ui.Widgets helpers)
%{type: :column, ...}
end
def handle_event(%Address{id: :email}, :change, value, state) do
{:noreply, %{state | email: value}}
end
def handle_event(%Address{id: :submit}, :tap, _, state) do
# Escalate to parent — this is the "semantic" event.
send(state.parent_pid, {:form_submitted, state.email})
{:noreply, state}
end
end
Summary
Callbacks
@callback handle_event( addr :: Dala.Event.Address.t(), event :: atom(), payload :: term(), state :: map() ) :: {:noreply, map()}