A simple base class for creating fast, lightweight web components
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
HTML templating with lit-html providing efficient rendering, event binding, and directive support. The template system enables declarative UI definition with optimized re-rendering and powerful templating features.
Creates HTML template results for rendering dynamic content.
/**
* Tagged template literal for creating HTML templates
* @param strings Template literal strings
* @param values Template literal values (expressions)
* @returns Template result for rendering
*/
function html(strings: TemplateStringsArray, ...values: unknown[]): TemplateResult;
/**
* Template result interface for HTML content
*/
interface TemplateResult {
readonly strings: TemplateStringsArray;
readonly values: readonly unknown[];
readonly type: ResultType;
}Usage Examples:
import { LitElement, html } from "lit-element";
class MyElement extends LitElement {
name = "World";
items = ["apple", "banana", "cherry"];
render() {
return html`
<div>
<h1>Hello, ${this.name}!</h1>
<ul>
${this.items.map(item => html`<li>${item}</li>`)}
</ul>
<button @click=${this.handleClick}>Click me</button>
</div>
`;
}
private handleClick(e: Event) {
console.log("Button clicked");
}
}Creates SVG template results for rendering SVG content.
/**
* Tagged template literal for creating SVG templates
* @param strings Template literal strings
* @param values Template literal values (expressions)
* @returns SVG template result for rendering
*/
function svg(strings: TemplateStringsArray, ...values: unknown[]): SVGTemplateResult;
/**
* Template result interface for SVG content
*/
interface SVGTemplateResult extends TemplateResult {
readonly type: typeof SVG_RESULT;
}Usage Examples:
import { LitElement, html, svg } from "lit-element";
class MyElement extends LitElement {
render() {
return html`
<div>
${svg`
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" />
<text x="50" y="55" text-anchor="middle" fill="white">SVG</text>
</svg>
`}
</div>
`;
}
}Creates MathML template results for rendering mathematical notation.
/**
* Tagged template literal for creating MathML templates
* @param strings Template literal strings
* @param values Template literal values (expressions)
* @returns MathML template result for rendering
*/
function mathml(strings: TemplateStringsArray, ...values: unknown[]): MathMLTemplateResult;
/**
* Template result interface for MathML content
*/
interface MathMLTemplateResult extends TemplateResult {
readonly type: typeof MATHML_RESULT;
}Renders template results to DOM containers.
/**
* Renders a template result to a DOM container
* @param value Template result or other renderable value
* @param container Element or DocumentFragment to render into
* @param options Rendering options
* @returns Root part for the rendered content
*/
function render(
value: unknown,
container: Element | DocumentFragment,
options?: RenderOptions
): RootPart;
/**
* Root part returned by render function
*/
interface RootPart {
readonly type: PartType;
readonly options: RenderOptions;
setConnected(isConnected: boolean): void;
}Usage Examples:
import { html, render } from "lit-element";
// Render to existing DOM element
const container = document.getElementById("app");
const template = html`<h1>Hello, World!</h1>`;
render(template, container);
// Render with options
render(template, container, {
host: this,
isConnected: true
});Special sentinel values for template control.
/**
* Sentinel value representing no content to render
*/
const nothing: symbol;
/**
* Sentinel value indicating no change should be made
*/
const noChange: symbol;Usage Examples:
import { LitElement, html, nothing, noChange } from "lit-element";
class MyElement extends LitElement {
showContent = false;
cachedValue = "";
render() {
return html`
<div>
${this.showContent ? html`<p>Content here</p>` : nothing}
<p>${this.shouldUpdateValue() ? this.cachedValue : noChange}</p>
</div>
`;
}
private shouldUpdateValue(): boolean {
// Custom logic to determine if value should update
return Date.now() % 1000 > 500;
}
}Binding event listeners in templates.
/**
* Event listener binding syntax in templates
* Use @eventname=${handler} syntax
*/Usage Examples:
import { LitElement, html } from "lit-element";
class MyElement extends LitElement {
count = 0;
render() {
return html`
<div>
<button @click=${this.increment}>Increment</button>
<button @click=${this.decrement}>Decrement</button>
<input @input=${this.handleInput} @keydown=${this.handleKeydown} />
<div @mouseenter=${this.handleMouseenter} @mouseleave=${this.handleMouseleave}>
Hover me
</div>
<p>Count: ${this.count}</p>
</div>
`;
}
private increment() {
this.count++;
}
private decrement() {
this.count--;
}
private handleInput(e: Event) {
const input = e.target as HTMLInputElement;
console.log("Input value:", input.value);
}
private handleKeydown(e: KeyboardEvent) {
if (e.key === "Enter") {
console.log("Enter pressed");
}
}
private handleMouseenter() {
console.log("Mouse entered");
}
private handleMouseleave() {
console.log("Mouse left");
}
}Binding properties and attributes in templates.
/**
* Property binding: .property=${value}
* Attribute binding: attribute=${value}
* Boolean attribute binding: ?attribute=${boolean}
*/Usage Examples:
import { LitElement, html } from "lit-element";
class MyElement extends LitElement {
isDisabled = false;
inputValue = "default";
customData = { key: "value" };
render() {
return html`
<div>
<!-- Attribute binding -->
<input value=${this.inputValue} placeholder="Enter text" />
<!-- Property binding -->
<my-child .data=${this.customData}></my-child>
<!-- Boolean attribute binding -->
<button ?disabled=${this.isDisabled}>Click me</button>
<!-- Conditional classes -->
<div class="item ${this.isDisabled ? 'disabled' : 'enabled'}">
Content
</div>
</div>
`;
}
}Composing templates with other templates and expressions.
/**
* Templates can contain other templates and complex expressions
*/Usage Examples:
import { LitElement, html } from "lit-element";
class MyElement extends LitElement {
items = [
{ id: 1, name: "Item 1", active: true },
{ id: 2, name: "Item 2", active: false },
{ id: 3, name: "Item 3", active: true }
];
render() {
return html`
<div>
${this.renderHeader()}
${this.renderItems()}
${this.renderFooter()}
</div>
`;
}
private renderHeader() {
return html`
<header>
<h1>My Items</h1>
<p>Total: ${this.items.length}</p>
</header>
`;
}
private renderItems() {
return html`
<ul>
${this.items.map(item => this.renderItem(item))}
</ul>
`;
}
private renderItem(item: any) {
return html`
<li class=${item.active ? 'active' : 'inactive'}>
<span>${item.name}</span>
${item.active ? html`<span class="badge">Active</span>` : ''}
</li>
`;
}
private renderFooter() {
const activeCount = this.items.filter(item => item.active).length;
return html`
<footer>
<p>Active items: ${activeCount}</p>
</footer>
`;
}
}Understanding the part system used internally by lit-html.
/**
* Union type for all part types in lit-html
*/
type Part =
| ChildPart
| AttributePart
| PropertyPart
| BooleanAttributePart
| EventPart
| ElementPart;
/**
* Part types enumeration
*/
enum PartType {
ATTRIBUTE = 1,
CHILD = 2,
PROPERTY = 3,
BOOLEAN_ATTRIBUTE = 4,
EVENT = 5,
ELEMENT = 6
}
/**
* Information about a part for directives
*/
interface PartInfo {
readonly type: PartType;
readonly strings?: ReadonlyArray<string>;
readonly name?: string;
readonly tagName?: string;
}