Macaw.Component.Context (macaw_component v0.1.5)

Copy Markdown View Source

The context a component renders in (spec/02 §2): its mode, instance, size, root font size, heading level, theme, the viewer's preferences, the holder's now, and the cell's resolved bindings.

The host computes it: on a page the core, elsewhere the adopter. The component never knows which, and never reads a clock: now is the holder's. bindings is %{slot => %{role => field | [field, ...]}}, each slot's binding as Macaw.Component.Slot.resolve/3 resolves it, so a component reads the field bound to a role with field/3 and never repeats the defaulting rule.

iex> {:ok, ctx} = Macaw.Component.Context.new(mode: :live, instance: "cards-1", size: {640, 400}, now: ~U[2026-10-28 12:00:00Z])
iex> {Macaw.Component.Context.heading(ctx, 0), Macaw.Component.Context.heading(ctx, 1)}
{"h2", "h3"}
iex> Macaw.Component.Context.id(ctx, "item-3")
"cards-1-item-3"
iex> {:ok, ctx} = Macaw.Component.Context.new(mode: :live, instance: "chart-1", size: {640, 400}, now: ~U[2026-10-28 12:00:00Z], bindings: %{"points" => %{"x" => "t", "y" => ["in", "out"]}})
iex> {Macaw.Component.Context.field(ctx, "points", "x"), Macaw.Component.Context.field(ctx, "points", "y"), Macaw.Component.Context.field(ctx, "points", "label")}
{"t", ["in", "out"], nil}

Summary

Functions

The field bound to role of slot: a string for a one-field role, the list of fields for a many role, nil for a slot or role the context does not bind.

The fields, in the order of spec/02 §2's table.

The heading element depth levels below the component's top (0 for its top): "h<level + depth>", never past "h6".

An element id unique to the instance, "<instance>-<local>", stable across renders. local is a non-empty string of letters, digits, - and _; anything else raises ArgumentError, a programming error in the component.

A context from a keyword list or a map: {:ok, context} or every fault at once, each {[field], reason}, an unknown field :unknown_key and a missing required one :required. The theme defaults to Macaw.Layers.Theme.default(). A bad binding is a fault at its path under [:bindings]: :not_a_map, :bad_name for a slot or role that is not a non-empty string, :not_a_field for a field that is neither a non-empty string nor a non-empty list of them.

Types

t()

@type t() :: %Macaw.Component.Context{
  bindings: %{
    required(String.t()) => %{
      required(String.t()) => String.t() | [String.t(), ...]
    }
  },
  heading_level: 1..6,
  instance: String.t(),
  measured: boolean(),
  mode: Macaw.Component.Mode.t(),
  now: DateTime.t(),
  preferences: %{zone: String.t(), units: atom(), shortcuts: map()},
  root_font_size: number(),
  size: {number(), number()},
  theme: Macaw.Layers.Theme.t()
}

Functions

field(context, slot, role)

@spec field(t(), String.t(), String.t()) :: String.t() | [String.t(), ...] | nil

The field bound to role of slot: a string for a one-field role, the list of fields for a many role, nil for a slot or role the context does not bind.

fields()

@spec fields() :: [atom(), ...]

The fields, in the order of spec/02 §2's table.

heading(context, depth)

@spec heading(t(), non_neg_integer()) :: String.t()

The heading element depth levels below the component's top (0 for its top): "h<level + depth>", never past "h6".

id(context, local)

@spec id(t(), String.t()) :: String.t()

An element id unique to the instance, "<instance>-<local>", stable across renders. local is a non-empty string of letters, digits, - and _; anything else raises ArgumentError, a programming error in the component.

new(attrs)

@spec new(keyword() | map()) :: {:ok, t()} | {:error, [Macaw.Component.fault(), ...]}

A context from a keyword list or a map: {:ok, context} or every fault at once, each {[field], reason}, an unknown field :unknown_key and a missing required one :required. The theme defaults to Macaw.Layers.Theme.default(). A bad binding is a fault at its path under [:bindings]: :not_a_map, :bad_name for a slot or role that is not a non-empty string, :not_a_field for a field that is neither a non-empty string nor a non-empty list of them.