@@ -8,62 +8,33 @@ Add a static template function in your `x-element` definition in order to
8
8
leverage automagical DOM generation and data binding:
9
9
10
10
``` javascript
11
- static template (html , { map } ) {
11
+ static template (html ) {
12
12
return ({ options, selectedId }) => {
13
13
return html `
14
14
<select name =" my-options" >
15
- ${ map (options, option => option .id , option => html `
16
- <option value =" ${option.value}" ?selected =" ${option.id === selectedId}" >
17
- ` )}
15
+ ${ options .map (option => [
16
+ option .id ,
17
+ html ` <option value =" ${option.value}" ?selected =" ${option.id === selectedId}" >` ,
18
+ ])}
18
19
</select >
19
20
` ;
20
21
};
21
22
}
22
23
```
23
24
24
- The following binding types are supported:
25
+ The following bindings are supported:
25
26
26
- | Type | Example |
27
- | :------------------ | :----------------------------------------- |
28
- | attribute | ` <span id="target" foo="${bar}"></span> ` |
29
- | attribute (boolean) | ` <span id="target" ?foo="${bar}"></span> ` |
30
- | attribute (defined) | ` <span id="target" ??foo="${bar}"></span> ` |
31
- | property | ` <span id="target" .foo="${bar}"></span> ` |
32
- | content | ` <span id="target">${foo}</span> ` |
33
-
34
- Emulates:
35
-
36
- ``` javascript
37
- const el = document .createElement (' div' );
38
- el .attachShadow ({ mode: ' open' });
39
- el .innerHTML = ' <span id="target"></span>' ;
40
- const target = el .shadowRoot .getElementById (' target' );
41
-
42
- // attribute value bindings set the attribute value
43
- target .setAttribute (' foo' , bar);
44
-
45
- // attribute boolean bindings set the attribute to an empty string or remove
46
- target .setAttribute (' foo' , ' ' ); // when bar is truthy
47
- target .removeAttribute (' foo' ); // when bar is falsy
48
-
49
- // attribute defined bindings set the attribute if the value is non-nullish
50
- target .setAttribute (' foo' , bar); // when bar is non-nullish
51
- target .removeAttribute (' foo' ); // when bar is nullish
52
-
53
- // property bindings assign the value to the property of the node
54
- target .foo = bar;
55
-
56
- // content bindings create text nodes for basic content
57
- const text = document .createTextNode (' ' );
58
- text .textContent = foo;
59
- target .append (text);
60
-
61
- // content bindings append a child for singular, nested content
62
- target .append (foo);
63
-
64
- // content binding maps and appends children for arrays of nested content
65
- target .append (... foo);
66
- ```
27
+ | Binding | Template | Emulates |
28
+ | :------------------ | :--------------------------- | :------------------------------------------------------------ |
29
+ | -- | -- | ` const el = document.createElement('div'); ` |
30
+ | attribute | ` <div foo="${bar}"></div> ` | ` el.setAttribute('foo', bar); ` |
31
+ | attribute (boolean) | ` <div ?foo="${bar}"></div> ` | ` el.setAttribute('foo', ''); // if “bar” is truthy ` |
32
+ | -- | -- | ` el.removeAttribute('foo'); // if “bar” is falsy ` |
33
+ | attribute (defined) | ` <div ??foo="${bar}"></div> ` | ` el.setAttribute('foo', bar); // if “bar” is non-nullish ` |
34
+ | -- | -- | ` el.removeAttribute('foo'); // if “bar” is nullish ` |
35
+ | property | ` <div .foo="${bar}"></div> ` | ` el.foo = bar; ` |
36
+ | content | ` <div>${foo}</div> ` | ` el.append(document.createTextNode(foo)) // if “bar” is text ` |
37
+ | -- | -- | (see [ content binding] ( #content-binding ) for composition) |
67
38
68
39
** Important note on serialization during data binding:**
69
40
@@ -78,12 +49,6 @@ The following template languages are supported:
78
49
* ` html `
79
50
* ` svg `
80
51
81
- The following value updaters are supported:
82
-
83
- * ` map ` (can be used with content bindings)
84
- * ` unsafe ` (can be used with content bindings)
85
- * ` live ` (can be used with property bindings)
86
-
87
52
** A note on non-primitive data:**
88
53
89
54
Because DOM manipulation is * slow* — template engines do their best to avoid it
@@ -216,23 +181,6 @@ html`<div .foo="${bar}"></div>`;
216
181
// el.foo = bar;
217
182
```
218
183
219
- #### The ` live ` property binding
220
-
221
- You can wrap the property being bound in the ` live ` updater to ensure that each
222
- ` render ` call will sync the template‘s value into the DOM. This is primarily
223
- used to control form inputs.
224
-
225
- ``` js
226
- const bar = ' something' ;
227
- html ` <input .value =" ${live(bar)}" >` ;
228
- // <input>
229
- // el.value = bar;
230
- ```
231
-
232
- The key difference to note is that the basic property binding will not attempt
233
- to perform an update if ` value === lastValue ` . The ` live ` binding will instead
234
- check if ` value === el.value ` whenever a ` render ` is kicked off.
235
-
236
184
### Content binding
237
185
238
186
The content binding does different things based on the value type passed in.
@@ -283,7 +231,7 @@ html`<div>${bar}</div>`;
283
231
284
232
#### Array content binding
285
233
286
- When the content being bound is an array of template results, you get a mapping .
234
+ When the content being bound is an array of template results, you get a list .
287
235
288
236
``` js
289
237
const bar = [
@@ -300,14 +248,16 @@ html`<div>${bar}</div>`;
300
248
// <div><span>one</span><span>two</span></div>
301
249
```
302
250
303
- #### The ` map ` content binding
251
+ #### Map content binding
304
252
305
- The ` map ` content binding adds some special behavior on top of the basic array
306
- content binding. In particular, it _ keeps track_ of each child node based on
307
- an ` identify ` function declared by the caller. This enables the template engine
308
- to _ move_ child nodes under certain circumstances (versus having to constantly
309
- destroy and recreate). And that shuffling behavior enables authors to animate
310
- DOM nodes across such transitions.
253
+ When the content being bound is an array of key-value map entries (where the
254
+ ` key ` is a unique string within the list and the ` value ` is a template result),
255
+ you get also list. But, this value will come with some special behavior on top
256
+ of the basic array content binding. In particular, it _ keeps track_ of each
257
+ child node based on the given ` key ` you declare. This enables the template
258
+ engine to _ move_ child nodes under certain circumstances (versus having to
259
+ constantly destroy and recreate). And that shuffling behavior enables authors to
260
+ animate DOM nodes across such transitions.
311
261
312
262
``` js
313
263
// Note that you can shuffle the deck without destroying / creating DOM.
@@ -318,41 +268,12 @@ const deck = [
318
268
];
319
269
const items = deck;
320
270
const identify = item => item .id ;
321
- const callback = item => html ` <span >${ item .text } </span >` ;
322
- const bar = map (items, identify, callback );
271
+ const template = item => html ` <span >${ item .text } </span >` ;
272
+ const bar = items . map (item => [ identify (item), template (item)] );
323
273
html ` <div >${ bar} </div >` ;
324
274
// <div><span>♥1</span>…<span>♣A</span></div>
325
275
```
326
276
327
- #### The ` unsafe ` content binding
328
-
329
- The ` unsafe ` content binding allows you to parse / instantiate text from a
330
- trusted source. This should _ only_ be used to inject trusted content — never
331
- user content.
332
-
333
- ``` js
334
- const bar = ' <script>console.prompt("can you hear me now?")</script>' ;
335
- html ` <div >${ unsafe (bar, ' html' )} </div >` ;
336
- // <div><script>console.prompt("can you hear me now?")</script></div>
337
- // console.prompt('can you hear me now?');
338
-
339
- const bar = ' <circle cx="50" cy="50" r="50"></circle>' ;
340
- html `
341
- <svg
342
- xmlns =" http://www.w3.org/2000/svg"
343
- viewBox =" 0 0 100 100" >
344
- ${ unsafe (bar, ' svg' )}
345
- </svg >
346
- ` ;
347
- //
348
- // <svg
349
- // xmlns="http://www.w3.org/2000/svg"
350
- // viewBox="0 0 100 100">
351
- // <circle cx="50" cy="50" r="50"></circle>
352
- // </svg>
353
- //
354
- ```
355
-
356
277
## Customizing your base class
357
278
358
279
Following is a working example using [ lit-html] ( https://lit.dev ) :
0 commit comments