Noizu.Tessera.Component (Noizu.Tessera v0.2.0)

Copy Markdown View Source

use Noizu.Tessera.Component, tag: "persona-card", js: "persona_card.mjs"

Turns a module into a tessera component:

  • the attr / prop / event / slot / cy DSL declares the wire contract (CONTRACT.md §1); everything is validated at compile time and raises CompileError with a pointed message;
  • the module gains __tessera_spec__/0 (a Noizu.Tessera.Spec struct) and __tessera_manifest__/0 (a plain map);
  • at compile time the generated JS contract module (<snake_tag>.contract.generated.mjs, CONTRACT.md §2) is written next to the component's .mjs — only when its content changed; the .mjs is an @external_resource, so touching it recompiles and regenerates;
  • when Hologram is available (Code.ensure_loaded?(Hologram.Component)) the same module becomes a Hologram component via Noizu.Tessera.Hologram.Adapter (CONTRACT.md §3/§5). Without Hologram the module stays spec-only (the JS contract still generates).

DSL

use Noizu.Tessera.Component, tag: "persona-card", js: "persona_card.mjs"

attr :display_name, :string, required: true
attr :disabled, :boolean, default: false
prop :tag_list, :list, json: true, default: []
prop :filters, :map, json: true
event "persona-select", detail: %{persona_id: :string, click_count: :integer}
slot "header"
css "--persona-card-accent", default: "#6366f1"
part "select-button"
cy "persona-card-root"

styles ~CSS":host { border-color: var(--tsr-persona-card-accent, #6cf); }"

Element DSL (template-bearing components): state, action, the lifecycle hooks should_update / will_update / first_updated / updated (each fn state, changed -> ... end), and ?attr={expr} boolean attribute bindings in the template. attr/prop/state accept Lit property options attribute: "custom-name" | false and reflect: true; :list types emit Lit's Array converter.

Naming rules (CONTRACT.md §1): attr/prop/detail names are snakecase atoms; attr names reach the DOM kebab-cased, prop names camelCased; event names are kebab-case strings matching ^[a-z][a-z0-9]*(-[a-z0-9]+)+$. Each event also gets a binding prop `on<event>(e.g.on_persona_select) whose value is:action(targetpage) or{:action, target: "layout" | cid}`.

When Hologram is loaded, prop is Hologram's own prop/2,3 macro (imported by use Hologram.Component); tessera opts json: and default: ride along and are interpreted by this module's compiler. The attr macro additionally declares the Hologram prop behind the scenes, and each event declares its on_<event> binding prop — all during module-body expansion, so Hologram's @__props__ accumulator is complete before Hologram's __before_compile__ runs (hooks run in registration order, hologram's first).

Reserved names: the generated component defines __tessera_*__ helpers and template/0 — do not define them by hand.