reflection

Attribute/property reflection

observed attributes reflect to/from their backing property.

Rule id reflection — run only this rule with banira lint src/*.ts --rules reflection.

Why it matters

An observed attribute and its property should stay in sync: setting the property updates the attribute (property → attribute), and changing the attribute updates the element (attribute → property). Frameworks, templates and tooling rely on this round-trip; when it's missing, el.value = 'x' and el.setAttribute('value', 'x') drift apart. banira mounts the element and checks each observed attribute round-trips.

✗ Flagged

src/my-field.ts — property never writes the attribute
export class MyField extends HTMLElement {
  static observedAttributes = ['value'];
  #value = "";
  get value() { return this.#value; }
  // setting the property does NOT update the attribute → they diverge
  set value(v) { this.#value = v; }
}
customElements.define('my-field', MyField);

✓ Good

src/my-field.ts — property and attribute reflect both ways
export class MyField extends HTMLElement {
  static observedAttributes = ['value'];
  get value() { return this.getAttribute('value') ?? ''; }
  set value(v) { this.setAttribute('value', v); }      // property → attribute
  attributeChangedCallback() { this.render(); }         // attribute → element
}
customElements.define('my-field', MyField);