StatifierBlocks.Map.Info (StatifierBlocks v0.40.0)

Copy Markdown View Source

The Map's description region, as data: one structured description for every element StatifierBlocks.Map.graph/2 draws, and one for the document itself when nothing is selected.

A host draws the region beside the map and keeps it there. It shows the selected block's description, or idle/4's answer when no block is selected. It is the screen-reader twin of the map: the map region is aria-hidden, so anything a sighted reader learns by looking at a box has to be sayable in words here, and every row of the host's list points at the region with aria-describedby.

Where every fact comes from

Nothing here is a second reading of the document. Every fact is asked of something the page already builds:

FactAsked of
which elements there are, and their idsStatifierBlocks.Map.graph/2
a block's title and sentenceViewModel.title/1, and ViewModel.sentence/1 with its event names read through the host's :phrase
a block's notethe block's own note field, in the document
a block's settingsViewModel.shown_fields/1: the fields the type's config_schema/1 declares, with their values
where a block sitsViewModel.positions/1
its outcomes and where each goesStatifierBlocks.Describe.outline/3's :sequence and :exit edges
the interrupt rules that can leave itthe outline's :interrupt edges
what an arm goes tothe outline's :branch edges
what a connector carriesthe outline's :sequence edge between the same two blocks
what a timer edge says, and what a send arms or a rule hearsthe outline's :timer edges, and a timer edge's line in Describe.render/2
what a type is forStatifierBlocks.BlockType.explain/1 of the block's type, through the palette

A type's explanation is the package's: the paragraph its optional explain/0 callback answers, else its palette entry's description. Two cases it has no answer for are said here: a block whose type the palette cannot resolve, and a type that neither explains itself nor carries a description.

The settings are values, never controls: this is a description, and the one place a value is changed stays the host's form.

The note

A block whose document carries an author-written note for it has that note as its description's note, and the region shows it above the built-in text: before the sentence, the type's explanation and the facts (ADR-0001's Amendment of 2026-09-28, clause 2g). A block with no note, or a note that is only whitespace, has note: nil and reads as it did. Only a block, and a rule, which is a block, carries one.

The host's words

elements/6 takes the :phrase option StatifierBlocks.Map.graph/2 takes, a function from an event name to the words a reader reads for it or nil, and reads a block's sentence, a rule's event and a timer edge's line through it, in the Map's own sentence shapes. A host passes the same function to both, so the region says what the box says. Without it every name stays as authored. The places a name is a value rather than prose keep the name: a block's settings and what a document or a rule listens for.

The kinds

An element's kind says what it is on the map. :block and :rule are boxes for blocks - a rule is a block in a group's interrupt rules; :arm, :undecided_arm, :rules, :body and :tray are a block's slots drawn as boxes of their own, :body being a group's body, drawn as a pane beside its rules; :marker is an empty slot's "Nothing here yet"; :end is a final mark where the document finishes, one per outcome it finishes with (done, and abandon where an interrupt rule abandons its last step), and the edge into it is an :edge that names the outcome; :start is the filled dot the document starts at, and its edge into the first step is a :start too; :edge is a connector, a branch's rejoin among them; :interrupt is the dashed edge an interrupt rule draws to where it takes its group; :timer is the dotted edge from a send with a delay to the rule or the wait that hears the event it sends; and :idle is the document, described when nothing is selected. A branch's description names its arms in order, which is what the band over them on the map says. Each description is keyed by the id the map draws it under, so the Map hook, StatifierBlocksMap, looks one up by the element under the pointer without asking the server.

Hover

Pointing at a drawn element shows that element's description, in the browser, in a hover layer drawn in the region's place, and pointing away hides the layer, so the region shows again: the selected block's description, or the idle one. The region itself is never written on a hover, so what it announces changes only on a selection. It pushes nothing and changes no selection. The hook reads two ids off its own element: data-info-hover, the hover layer's, and data-info-store, a hidden element holding one child per description, data-describes naming the map id and its inner markup what the region shows for it. A host that stamps neither gets a map with no hover.

Summary

Types

One labelled fact: a single value, or a list of them.

What an element is on the map; see the moduledoc.

The options elements/6 takes; see the moduledoc's "The host's words".

t()

One element described. id is the map's id for it (nil for the idle description); note is the author's note on a block, shown above the rest, or nil; sentence is left nil where it would only repeat title; settings are a block's configured values and facts everything else a reader needs, both in reading order.

Functions

Every element graph draws, described, in the order a walk of the graph meets them: a box, then what is inside it, then its connectors.

The document described, for when nothing is selected: its name and description, what starts it, how to read the map, and how many steps and open slots it has.

Types

fact()

@type fact() :: {String.t(), String.t() | [String.t()]}

One labelled fact: a single value, or a list of them.

kind()

@type kind() ::
  :block
  | :rule
  | :arm
  | :undecided_arm
  | :rules
  | :body
  | :tray
  | :marker
  | :end
  | :start
  | :edge
  | :interrupt
  | :timer
  | :idle

What an element is on the map; see the moduledoc.

option()

@type option() :: {:phrase, (String.t() -> String.t() | nil)}

The options elements/6 takes; see the moduledoc's "The host's words".

t()

@type t() :: %StatifierBlocks.Map.Info{
  explanation: String.t(),
  facts: [fact()],
  id: String.t() | nil,
  kind: kind(),
  note: String.t() | nil,
  sentence: String.t() | nil,
  settings: [fact()],
  title: String.t()
}

One element described. id is the map's id for it (nil for the idle description); note is the author's note on a block, shown above the rest, or nil; sentence is left nil where it would only repeat title; settings are a block's configured values and facts everything else a reader needs, both in reading order.

Functions

elements(document, graph, view_model, outline, palette, opts \\ [])

Every element graph draws, described, in the order a walk of the graph meets them: a box, then what is inside it, then its connectors.

document is the document view_model was built from, which a block's note is read from; graph is StatifierBlocks.Map.graph/2 of view_model, outline is Describe.outline/3 of the same document, and palette is the one both were built with, which a block's explanation is asked through. opts takes :phrase, the function the graph was built with. The graph's timer edges come last.

idle(document, graph, view_model, describe)

The document described, for when nothing is selected: its name and description, what starts it, how to read the map, and how many steps and open slots it has.