Concorde decorator — @ancestorAttribute. The @ancestorAttribute decorator automatically injects the value of an ancestor's attribute into a class property at the time of connectedCallback. Doc ID: docs/_decorators/ancestor-attribute. Keywords: Concorde, supersoniks, docs/_decorators/ancestor-attribute, ancestor-attribute, @ancestorAttribute, decorator, ancestorAttribute, connectedCallback, HTML.getAncestorAttributeValue, dataProvider, testAttribute, dynamic: false, formDataProvider, wordingProvider. URL: https://concorde.supersoniks.org/crawl/docs/_decorators/ancestor-attribute.html.
@ancestorAttribute
The @ancestorAttribute decorator automatically injects the value of an ancestor's attribute into a class property at the time of connectedCallback.
Principle
This decorator uses HTML.getAncestorAttributeValue to traverse up the DOM tree from the current element and find the first ancestor that has the specified attribute. The value of this attribute is then assigned to the decorated property.
Usage
Import
import { ancestorAttribute } from "@supersoniks/concorde/decorators";
Basic example
The component reads dataProvider and testAttribute from its ancestor wrapper. By default (dynamic: false), values are read once at connect.
import { html, LitElement } from "lit";
import { customElement } from "lit/decorators.js";
import { ancestorAttribute } from "@supersoniks/concorde/decorators";
@customElement("demo-ancestor-attribute")
export class DemoAncestorAttribute extends LitElement {
@ancestorAttribute("dataProvider")
dataProvider: string | null = null;
@ancestorAttribute("testAttribute")
testAttribute: string | null = null;
render() {
return html`
<p>dataProvider: <strong>${this.dataProvider ?? "null"}</strong></p>
<p>testAttribute: <strong>${this.testAttribute ?? "null"}</strong></p>
`;
}
}
<div dataProvider="demoDataProvider" testAttribute="test-value-123">
<docs-demo-sources for="demo-ancestor-attribute"></docs-demo-sources>
<demo-ancestor-attribute></demo-ancestor-attribute>
</div>
Use cases
This decorator is particularly useful for:
- Retrieving the
dataProviderfrom an ancestor without having to pass it explicitly - Retrieving the
formDataProviderin form components - Retrieving the
wordingProviderfor translation - Retrieving any other attribute defined on an ancestor
Behavior
- The search starts from the current element and traverses up the DOM tree
- The injection happens automatically at the time of
connectedCallback - By default (
dynamic: false), the value is read once at connect time and is not updated afterward - With
{ dynamic: true }, the property stays in sync when:- an ancestor changes the attribute value
- a closer ancestor gains the attribute (that value wins)
- the nearest ancestor loses the attribute (falls back to the next one up, or
null)
- When
dynamicis enabled, updates also propagate to@subscribe/@bindpaths that depend on the decorated property (e.g.${dataProvider})
Dynamic mode
Use { dynamic: true } when the decorated property must follow the DOM. With Lit, add @state() on the same property so template updates are visible when the observer assigns a new value.
The live demo below shows only the resolved attribute value — no store, no reparenting.
@customElement("demo-ancestor-attribute-dynamic")
export class DemoAncestorAttributeDynamic extends LitElement {
@ancestorAttribute("dataProvider", { dynamic: true })
@state()
dataProvider: string | null = null;
render() {
return html`
<p>Nearest ancestor: <strong>${this.dataProvider ?? "null"}</strong></p>
`;
}
}
Try in the demo:
- parent-a / parent-b — change the value on the direct parent
- Remove parent attr — falls back to outer
- Add closer — a wrapper with
from-closerbecomes the nearest ancestor - Remove closer — back to parent or outer
- Remove outer attr — if parent has no attribute either, the child shows
null
<docs-demo-sources for="demo-ancestor-attribute-dynamic-section"></docs-demo-sources>
<demo-ancestor-attribute-dynamic-section></demo-ancestor-attribute-dynamic-section>
Static mode (default) — read once at connect, no observer:
@ancestorAttribute("dataProvider")
dataProvider: string | null = null;
Notes
- This decorator works with any component that has a
connectedCallbackmethod (such asLitElementor components extendingSubscriber) - The search also traverses Shadow DOM if necessary
- If multiple ancestors have the attribute, the closest one will be used