# `Macaw.Data.Event`
[🔗](https://github.com/dcoai/macaw_data/blob/v0.5.3/lib/macaw/data/event.ex#L1)

The one interaction shape every component emits (Macaw spec 02 §8).

It lives in `macaw_data`, the smallest Macaw package, so an adopter using
no other Macaw library (visualize, standalone) emits the same value it
emits on a Macaw page.

- `name`: the event's name, a string the component declares (`"pick"`,
  `"brush"`).
- `instance`: the emitting instance's id.
- `element`: what was acted on. `item` is the element's stable id;
  `path` lists its enclosing elements, innermost first; `frame` is set
  only by components with an inner coordinate tree (a visual's frame).
- `identity`: the item's **declared** identity (`%{field => value}`),
  when it maps to data. Inference from other fields is the component's,
  only for a visitor's one-off pick, never for tracking.
- `value`: the event's own value: a window, a chosen option.
- `initiator`: `:visitor` or `:system`, which separates a view path's
  steps from its markers.
- `time`: the holder's now (a surface's, or a standalone holder's), never
  a clock read by the component.
- `point`: where, in the drawing; live only.
- `modifiers`: the keys held, from `:shift`, `:alt`, `:ctrl` and `:meta`.
- `row`: the data row, delivered to the host, **never recorded**.

**The recorded form** (`recordable/1`) drops `row` and `point`. Records,
observation and state snapshots only ever see it, so row values never
reach them; `identity` and `value` do, and whether they are recorded is
decided per state source by capture level.

Decoding a click from the wire and resolving it against the drawing it
landed on (the drawn-token rule) belong to the component that drew it,
not here.

# `element`

```elixir
@type element() :: %{frame: id() | nil, item: id() | nil, path: [id()]}
```

# `id`

```elixir
@type id() :: term()
```

# `modifier`

```elixir
@type modifier() :: :shift | :alt | :ctrl | :meta
```

# `recorded`

```elixir
@type recorded() :: %{
  name: String.t(),
  instance: String.t(),
  element: element(),
  identity: %{optional(term()) =&gt; term()} | nil,
  value: term(),
  initiator: :visitor | :system,
  time: DateTime.t(),
  modifiers: [modifier()]
}
```

The recorded form: an event without its data row or point.

# `t`

```elixir
@type t() :: %Macaw.Data.Event{
  element: element(),
  identity: %{optional(term()) =&gt; term()} | nil,
  initiator: :visitor | :system,
  instance: String.t(),
  modifiers: [modifier()],
  name: String.t(),
  point: {number(), number()} | nil,
  row: map() | nil,
  time: DateTime.t(),
  value: term()
}
```

# `fields`

```elixir
@spec fields() :: [atom()]
```

The struct's fields, in spec order.

# `new`

```elixir
@spec new(keyword() | map()) :: {:ok, t()} | {:error, [{atom() | term(), String.t()}]}
```

Builds an event from a keyword list or map, checking every field:
`{:ok, event}`, or `{:error, faults}` naming each bad field. Unknown
fields are faults too, never silently dropped.

# `recordable`

```elixir
@spec recordable(t()) :: recorded()
```

The recorded form: everything but `row` and `point`, as a plain map. What
records, observation and state snapshots see.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
