Feature: #91810 - Introduce lit-html and lit-element as client-side templating engine
See forge#91810
Description
To avoid custom jQuery template building a new slim client-side templating
engine lit-html together with lit-element is introduced. The modules
are avilable via the umbrella javascript module lit
.
This templating engine supports conditions, iterations, events, virtual DOM, data-binding and mutation/change detections in templates.
Impact
Individual client-side templates can be processed in JavaScript directly using modern web technologies like template-strings and template-elements.
Rendering is handled by the AMD-modules lit-
and lit-
.
Please consult the lit-
template-reference and lit-element-guide for more
information.
Examples
Variable assignment
import {html, render} from 'lit';
const value = 'World';
const target = document.getElementById('target');
render(html`<div>Hello ${value}!</div>`, target);
<div>Hello World!</div>
Unsafe tags would have been encoded (e.g.
<b>World</
as
<b>World</
).
Condition and iteration
import {html, render} from 'lit';
import {classMap} from 'lit/directives/class-map.js';
const items = ['a', 'b', 'c']
const classes = { list: true };
const target = document.getElementById('target');
const template = html`
<ul class=${classMap(classes)}">
${items.map((item: string, index: number): string => {
return html`<li>#${index+1}: ${item}</li>`
})}
</ul>
`;
render(template, target);
<ul class="list">
<li>#1: a</li>
<li>#2: b</li>
<li>#3: c</li>
</ul>
The
$
literal used in template tags can basically contain any
JavaScript instruction - as long as their result can be casted to string
again or is of type lit.
. This allows to
make use of custom conditions as well as iterations:
- condition:
$
{condition ? then Return : else Return} - iteration:
$
{array. map ( (item) => { return item; })}
Events
Events can be bound using the @
attribute prefix.
import {html, render} from 'lit';
const value = 'World';
const target = document.getElementById('target');
const template = html`
<div @click="${(evt: Event): void => { console.log(value); })}">
Hello ${value}!
</div>
`;
render(template, target);
The result won't look much different from the first example - however the
custom attribute
@click
will be transformed into an according event
listener bound to the element where it has been declared.
Custom HTML elements
A web component based on the W3C custom elements (web-components_) specification
can be implemented using the Lit
base class.
import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators';
@customElement('my-element')
class MyElement extends LitElement {
// Declare observed properties
@property()
value: string = 'awesome';
// Avoid Shadow DOM so global styles apply to the element contents
createRenderRoot(): Element|ShadowRoot {
return this;
}
// Define the element's template
render() {
return html`<p>Hello ${this.value}!</p>`;
}
}
<my-element value="World"></my-element>
This is rendered as:
<my-element value="World">
<p>Hello world!</p>
</my-element>