Drafter.Event.Delegation (drafter v0.3.1)

Copy Markdown View Source

Routes an event to widgets related to a given widget in the hierarchy.

Every function takes a Drafter.WidgetHierarchy, the id of the widget the relation is measured from, and an event tuple, and returns {updated_hierarchy, actions} where actions is the concatenation of the actions each recipient produced.

Each recipient is focused before the event is handed to it, so the hierarchy returned has focus on the last widget dispatched to, not on the widget the call started from.

A selector narrows the recipients:

  • an atom — matches widgets whose module's last name segment, downcased, equals the atom (:button matches Drafter.Widget.Button)
  • {:class, class} — matches widgets whose state map has class in its :classes list
  • {:id, id} — matches the widget with that id

Anything else matches nothing. delegate_to_siblings/4 additionally accepts :all, its default, meaning every sibling.

Summary

Types

The hierarchy after every dispatch, and the actions the recipients returned.

Narrows which related widgets receive the event.

Functions

Dispatch event to every descendant of root_id, at every depth.

Dispatch event to the direct children of parent_id that match selector.

Dispatch event to the direct parent of child_id.

Dispatch event to the other children of widget_id's parent.

Types

result()

@type result() :: {Drafter.WidgetHierarchy.t(), [term()]}

The hierarchy after every dispatch, and the actions the recipients returned.

selector()

@type selector() ::
  atom() | {:class, atom()} | {:id, Drafter.WidgetHierarchy.widget_id()}

Narrows which related widgets receive the event.

An atom matches on widget type, {:class, class} on the widget state's :classes list, and {:id, id} on the widget id. Any other term matches nothing.

Functions

broadcast_to_descendants(hierarchy, root_id, event)

@spec broadcast_to_descendants(
  Drafter.WidgetHierarchy.t(),
  Drafter.WidgetHierarchy.widget_id(),
  term()
) ::
  result()

Dispatch event to every descendant of root_id, at every depth.

root_id itself does not receive it, and no selector is applied. A widget always receives the event before anything beneath it does.

delegate_to_children(hierarchy, parent_id, event, selector)

@spec delegate_to_children(
  Drafter.WidgetHierarchy.t(),
  Drafter.WidgetHierarchy.widget_id(),
  term(),
  selector()
) :: result()

Dispatch event to the direct children of parent_id that match selector.

selector is required and grandchildren are never matched. Children that do not match are left untouched. Returns {hierarchy, actions} with the actions concatenated in child order.

A parent_id that is not in the hierarchy has no children, so nothing is dispatched.

delegate_to_parent(hierarchy, child_id, event)

@spec delegate_to_parent(
  Drafter.WidgetHierarchy.t(),
  Drafter.WidgetHierarchy.widget_id(),
  term()
) ::
  result()

Dispatch event to the direct parent of child_id.

Returns {hierarchy, []} unchanged when child_id has no parent, which is the case for a root widget and for an id not in the hierarchy.

delegate_to_siblings(hierarchy, widget_id, event, selector \\ :all)

@spec delegate_to_siblings(
  Drafter.WidgetHierarchy.t(),
  Drafter.WidgetHierarchy.widget_id(),
  term(),
  selector() | :all
) :: result()

Dispatch event to the other children of widget_id's parent.

widget_id itself never receives the event. selector defaults to :all, meaning every sibling, and is otherwise a selector/0. Returns {hierarchy, []} unchanged when widget_id has no parent.