You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An optional layer that uses the `Schema` to automatically register `@attr`-style reactive properties for every **leaf binding** in the template — i.e. simple expressions like `{{foo}}` or `id="{{foo-bar}}"` that have no nested properties, no explicit type, and no child element references.
95
+
96
+
- The **attribute name** is the binding key exactly as written in the template (e.g. `foo-bar`).
97
+
- The **property name** is derived by removing all dashes (e.g. `foo-bar` → `foobar`).
98
+
- Properties already decorated with `@attr` or `@observable` are left untouched.
99
+
-`FASTElementDefinition.attributeLookup` and `propertyLookup` are patched so `attributeChangedCallback` correctly delegates to the new `AttributeDefinition`.
100
+
101
+
Enabled via `TemplateElement.options({ "my-element": { attributeMap: "all" } })`.
102
+
92
103
### Syntax constants (`syntax.ts`)
93
104
94
105
All delimiters used by the parser are defined in a single `Syntax` interface and exported as named constants from `syntax.ts`. This makes the syntax pluggable and easy to audit.
@@ -284,6 +295,15 @@ flowchart LR
284
295
285
296
For a deep dive into the schema structure, context tracking, and proxy system see [SCHEMA_OBSERVER_MAP.md](./SCHEMA_OBSERVER_MAP.md).
286
297
298
+
### AttributeMap and leaf bindings
299
+
300
+
When `attributeMap: "all"` is set, `AttributeMap.defineProperties()` is called after parsing. It iterates `Schema.getRootProperties()` and skips any property whose schema entry contains `properties`, `type`, or `anyOf` — keeping only plain leaf bindings. For each leaf:
301
+
302
+
1. The schema key (e.g. `foo-bar`) is used as the **attribute name**.
303
+
2. Dashes are removed to form the **JS property name** (e.g. `foobar`).
304
+
3. A new `AttributeDefinition` is registered via `Observable.defineProperty`.
305
+
4.`FASTElementDefinition.attributeLookup` and `propertyLookup` are updated so `attributeChangedCallback` can route attribute changes to the correct property.
Copy file name to clipboardExpand all lines: packages/fast-html/README.md
+27Lines changed: 27 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -217,6 +217,33 @@ if (process.env.NODE_ENV === 'development') {
217
217
}
218
218
```
219
219
220
+
#### `attributeMap`
221
+
222
+
When `attributeMap: "all"` is configured for an element, `@microsoft/fast-html` automatically creates reactive `@attr` properties for every **leaf binding** in the template — simple expressions like `{{foo}}` or `id="{{foo-bar}}"` that have no nested properties.
223
+
224
+
The **attribute name** is the binding key as written in the template. The **property name** is derived by removing all dashes (`foo-bar` → `foobar`). Properties already decorated with `@attr` or `@observable` on the class are left untouched.
225
+
226
+
```typescript
227
+
TemplateElement.options({
228
+
"my-element": {
229
+
attributeMap: "all",
230
+
},
231
+
});
232
+
```
233
+
234
+
With the template:
235
+
236
+
```html
237
+
<f-templatename="my-element">
238
+
<template>
239
+
<p>{{greeting}}</p>
240
+
<p>{{first-name}}</p>
241
+
</template>
242
+
</f-template>
243
+
```
244
+
245
+
This registers `greeting` (attribute `greeting`, property `greeting`) and `first-name` (attribute `first-name`, property `firstname`) as `@attr` properties on the element prototype, enabling `setAttribute("first-name", "Jane")` to trigger a template re-render automatically.
0 commit comments