A2UICore.Catalog.RefSpec (A2UICore v0.1.1)

Copy Markdown View Source

Which properties of a component refer to other components, and how to pull those references out of a component's properties.

A spec has three parts, mirroring the reference ComponentRefSpec:

  • single — properties holding one child (child, contentChild),
  • list — properties holding many children (children, tabs),
  • nested — for list properties whose items are objects, the keys inside each item that hold the child (tabs → child).

extract/2 returns {component_id, property_path} pairs. Property paths are the reference's: "child", "children[0]", "children.componentId" (a template), "tabs[1].child".

Specs are derived from catalog schemas by A2UICore.Catalog.ReferenceMap; a surface keeps one per component type.

Objects are traversed in sorted key order, so when a value holds several references the order is deterministic (the reference follows JSON insertion order).

iex> spec = A2UICore.Catalog.RefSpec.new(single: ["child"], list: ["children"])
iex> A2UICore.Catalog.RefSpec.extract(spec, %{"child" => "a", "children" => ["b", "c"]})
[{"a", "child"}, {"b", "children[0]"}, {"c", "children[1]"}]

Summary

Types

A child reference: the referenced component id and the property path it came from.

t()

Functions

True when key is a configured child property.

True when the spec names no child properties at all.

Extracts {component_id, property_path} pairs from a component's props according to the spec: single properties first, then list properties.

Extracts {component_id, relative_path} pairs from one property value (a component id, a {child: id} / {componentId: id, path: …} object, a list of those, or an object with nested child slots).

Builds a spec. Options: :single and :list (lists of property names) and :nested (%{list_property => [item_key]}).

Types

child_ref()

(since 0.1.0)
@type child_ref() :: {component_id :: String.t(), property_path :: String.t()}

A child reference: the referenced component id and the property path it came from.

t()

(since 0.1.0)
@type t() :: %A2UICore.Catalog.RefSpec{
  list: MapSet.t(String.t()),
  nested: %{optional(String.t()) => MapSet.t(String.t())},
  single: MapSet.t(String.t())
}

Functions

child_prop?(ref_spec, key)

(since 0.1.0)
@spec child_prop?(t(), String.t()) :: boolean()

True when key is a configured child property.

empty?(ref_spec)

(since 0.1.0)
@spec empty?(t()) :: boolean()

True when the spec names no child properties at all.

extract(spec, props)

(since 0.1.0)
@spec extract(t(), map()) :: [child_ref()]

Extracts {component_id, property_path} pairs from a component's props according to the spec: single properties first, then list properties.

from_value(value)

(since 0.1.0)
@spec from_value(term()) :: [{String.t(), String.t()}]

Extracts {component_id, relative_path} pairs from one property value (a component id, a {child: id} / {componentId: id, path: …} object, a list of those, or an object with nested child slots).

iex> A2UICore.Catalog.RefSpec.from_value(%{"componentId" => "item", "path" => "/rows"})
[{"item", "componentId"}]
iex> A2UICore.Catalog.RefSpec.from_value([%{"child" => "x"}, "y"])
[{"x", "[0].child"}, {"y", "[1]"}]

new(options \\ [])

(since 0.1.0)
@spec new(keyword()) :: t()

Builds a spec. Options: :single and :list (lists of property names) and :nested (%{list_property => [item_key]}).