Skip to content

Commit

Permalink
For your consideration — no more updaters.
Browse files Browse the repository at this point in the history
Just testing out a thought. I think we might consdier removign the
notion of updaters altogether — we might even remove `map`!
  • Loading branch information
theengineear committed Nov 23, 2024
1 parent 9c71f4b commit 769e656
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 348 deletions.
35 changes: 17 additions & 18 deletions doc/TEMPLATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ Add a static template function in your `x-element` definition in order to
leverage automagical DOM generation and data binding:

```javascript
static template(html, { map }) {
static template(html) {
return ({ options, selectedId }) => {
return html`
<select name="my-options">
${map(options, option => option.id, option => html`
<option value="${option.value}" ?selected="${option.id === selectedId}">
`)}
${options.map(option => [
option.id,
html`<option value="${option.value}" ?selected="${option.id === selectedId}">`,
])}
</select>
`;
};
Expand Down Expand Up @@ -48,10 +49,6 @@ The following template languages are supported:
* `html`
* `svg`

The following value updaters are supported:

* `map` (can be used with content bindings)

**A note on non-primitive data:**

Because DOM manipulation is *slow* — template engines do their best to avoid it
Expand Down Expand Up @@ -234,7 +231,7 @@ html`<div>${bar}</div>`;

#### Array content binding

When the content being bound is an array of template results, you get a mapping.
When the content being bound is an array of template results, you get a list.

```js
const bar = [
Expand All @@ -251,14 +248,16 @@ html`<div>${bar}</div>`;
// <div><span>one</span><span>two</span></div>
```

#### The `map` content binding
#### Map content binding

The `map` content binding adds some special behavior on top of the basic array
content binding. In particular, it _keeps track_ of each child node based on
an `identify` function declared by the caller. This enables the template engine
to _move_ child nodes under certain circumstances (versus having to constantly
destroy and recreate). And that shuffling behavior enables authors to animate
DOM nodes across such transitions.
When the content being bound is an array of key-value map entries (where the
`key` is a unique string within the list and the `value` is a template result),
you get also list. But, this value will come with some special behavior on top
of the basic array content binding. In particular, it _keeps track_ of each
child node based on the given `key` you declare. This enables the template
engine to _move_ child nodes under certain circumstances (versus having to
constantly destroy and recreate). And that shuffling behavior enables authors to
animate DOM nodes across such transitions.

```js
// Note that you can shuffle the deck without destroying / creating DOM.
Expand All @@ -269,8 +268,8 @@ const deck = [
];
const items = deck;
const identify = item => item.id;
const callback = item => html`<span>${item.text}</span>`;
const bar = map(items, identify, callback);
const template = item => html`<span>${item.text}</span>`;
const bar = items.map(item => [identify(item), template(item)]);
html`<div>${bar}</div>`;
// <div><span>♥1</span>…<span>♣A</span></div>
```
Expand Down
16 changes: 8 additions & 8 deletions test/test-initialization-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ it('errors are thrown in connectedCallback when template result fails to render'
class TestElement extends XElement {
static get properties() {
return {
strings: { default: () => [] },
strings: { default: () => ['one', 'two', 'three'] },
};
}
static template(html, { map }) {
static template(html) {
return ({ strings }) => {
// In this case, "map" will fail when bound to an attribute.
return html`<div foo="${map(strings, () => {}, string => html`${string}`)}"></div>`;
// In this case, the array will fail if items are not template results.
return html`<div>${strings}</div>`;
};
}
}
Expand All @@ -120,13 +120,13 @@ it('errors are thrown in connectedCallback when template result fails to render
class TestElement extends XElement {
static get properties() {
return {
strings: { default: () => [] },
strings: { default: () => ['one', 'two', 'three'] },
};
}
static template(html, { map }) {
static template(html) {
return ({ strings }) => {
// In this case, "map" will fail when bound to an attribute.
return html`<div foo="${map(strings, () => {}, string => html`${string}`)}"></div>`;
// In this case, the array will fail if items are not template results.
return html`<div>${strings}</div>`;
};
}
}
Expand Down
Loading

0 comments on commit 769e656

Please sign in to comment.