A library for constructing Web Components
npx @tessl/cli install tessl/npm-microsoft--fast-element@2.7.0FAST Element is a lightweight, performant library for building standards-compliant Web Components that work across all major browsers and can be used with any front-end framework or without one. It provides a comprehensive toolkit for creating reusable UI components with modern TypeScript support, featuring reactive data binding, efficient templating with tagged template literals, dependency injection, state management, and SSR hydration capabilities.
npm install @microsoft/fast-element// Main functionality
import { FASTElement, customElement, attr, html, css, observable } from "@microsoft/fast-element";
// Specialized imports
import { twoWay } from "@microsoft/fast-element/binding/two-way.js";
import { signal, Signal } from "@microsoft/fast-element/binding/signal.js";
import { state, reactive, watch } from "@microsoft/fast-element/state.js";
import { Context } from "@microsoft/fast-element/context.js";
import { DI, inject, singleton, transient } from "@microsoft/fast-element/di.js";
import { fixture, timeout } from "@microsoft/fast-element/testing.js";For CommonJS:
const { FASTElement, customElement, attr, html, css, observable } = require("@microsoft/fast-element");import { FASTElement, customElement, attr, html, css } from "@microsoft/fast-element";
// Define styles
const styles = css`
:host {
display: block;
padding: 16px;
background: var(--background-color, #f0f0f0);
}
.greeting {
font-size: 18px;
color: var(--text-color, #333);
}
`;
// Define template
const template = html<GreetingCard>`
<div class="greeting">
Hello, ${x => x.name}!
</div>
`;
// Define custom element
@customElement({
name: "greeting-card",
template,
styles
})
export class GreetingCard extends FASTElement {
@attr name: string = "World";
}FAST Element is built around several key architectural components:
Core custom element functionality for building reusable web components with lifecycle management, Shadow DOM, and attribute synchronization.
class FASTElement extends HTMLElement {
readonly $fastController: ElementController;
$emit(type: string, detail?: any, options?: Omit<CustomEventInit, "detail">): boolean | void;
connectedCallback(): void;
disconnectedCallback(): void;
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
}
function customElement(definition: PartialFASTElementDefinition): ClassDecorator;
function customElement(nameOrDefinition: string | PartialFASTElementDefinition): ClassDecorator;Template system using tagged template literals with efficient compilation, directive support, and reactive binding capabilities.
function html<TSource = any, TParent = any>(
strings: TemplateStringsArray,
...values: TemplateValue<TSource, TParent>[]
): ViewTemplate<TSource, TParent>;
class ViewTemplate<TSource = any, TParent = any> {
create(host?: Element): HTMLView<TSource, TParent>;
render(source: TSource, host: Element | string, hostBindingTarget?: Element): HTMLView<TSource, TParent>;
}Composable CSS system with tagged template literals, design tokens, and efficient style application strategies.
function css(strings: TemplateStringsArray, ...values: CSSValue[]): ElementStyles;
class ElementStyles {
behaviors?: HostBehavior[];
addStylesTo(target: StyleTarget): void;
removeStylesFrom(target: StyleTarget): void;
}Reactive data binding system supporting one-way, two-way, and event bindings with automatic dependency tracking and efficient updates.
function oneWay<T = any>(
expression: Expression<T>,
policy?: DOMPolicy,
isBindingVolatile?: boolean
): Binding<T>;
function listener<T = any>(
expression: Expression<T>,
options?: AddEventListenerOptions
): Binding<T>;
class Binding<TSource = any, TReturn = any, TParent = any> {
evaluate(source: TSource, context: ExecutionContext<TParent>): TReturn;
}Memory-efficient observable system with automatic dependency tracking, batch updates, and array observation capabilities.
function observable<T, K extends keyof T>(target: T, nameOrAccessor: K): void;
function observable<T, K extends keyof T>(target: T, nameOrAccessor: K, descriptor: PropertyDescriptor): PropertyDescriptor;
const Observable: {
binding<T>(evaluate: () => T, observer: ExpressionObserver, isVolatile?: boolean): ExpressionObserver<any, T>;
track<T>(target: T, propertyName: keyof T): void;
notify(source: any, args: any): void;
};Built-in template directives for common patterns like conditionals, loops, references, and DOM node observation.
function when<TSource = any, TParent = any>(
expression: Expression<any, TSource, TParent>,
templateOrTemplateExpression: ViewTemplate<TSource, TParent> | Expression<ViewTemplate<TSource, TParent>, TSource, TParent>
): HTMLDirective;
function repeat<TSource = any, TParent = any>(
expression: Expression<any[], TSource, TParent>,
template: ViewTemplate<any, TSource>,
options?: RepeatOptions
): RepeatDirective<TSource, TParent>;
function ref<TSource = any, TParent = any>(propertyName: keyof TSource): RefDirective;Attribute system with automatic type conversion, reflection options, and custom converters for seamless property-attribute synchronization.
function attr(config?: AttributeConfiguration): PropertyDecorator;
function attr(target: {}, property: string | symbol): void;
interface AttributeConfiguration {
attribute?: string;
mode?: AttributeMode;
converter?: ValueConverter;
}
const booleanConverter: ValueConverter;
const nullableBooleanConverter: ValueConverter;
const nullableNumberConverter: ValueConverter;Reactive state management with reactive objects, computed values, and change watchers for complex application state.
function state<T>(value: T, options?: StateOptions<T>): State<T>;
function computedState<T>(compute: ComputedInitializer<T>): ComputedState<T>;
function reactive<T extends object>(target: T): T;
function watch<T>(target: T, callback: (source: T, args: any) => void): void;
interface State<T> {
readonly value: T;
set(value: T): void;
}Full-featured dependency injection container with decorators, service registration, and hierarchical resolution.
function inject(...keys: Key[]): ParameterDecorator | PropertyDecorator;
function singleton<T extends Constructable>(RegisterTarget?: T): RegisterSelf<T>;
function transient<T extends Constructable>(RegisterTarget?: T): RegisterSelf<T>;
interface Container {
get<K extends Key>(key: K): Resolved<K>;
register(...registrations: Registration[]): Container;
createChild(config?: ContainerConfiguration): Container;
}
const DI: {
createContainer(config?: ContainerConfiguration): Container;
getOrCreateDOMContainer(node?: Node): DOMContainer;
};Context protocol for sharing data and services across component trees using events and dependency injection integration.
interface FASTContext<T> extends ContextDecorator<T> {
get(target: EventTarget): T;
provide(target: EventTarget, value: T): void;
request(target: EventTarget, callback: ContextCallback<T>, multiple?: boolean): void;
}
const Context: {
create<T>(name: string, initialValue?: T): FASTContext<T>;
setRequestStrategy(strategy: FASTContextRequestStrategy): void;
};Server-side rendering support with hydration capabilities for fast initial page loads and SEO optimization.
const HydrationMarkup: {
attributeMarkerName: string;
contentBindingStartMarker(index: number, targetNodeId: string): string;
contentBindingEndMarker(index: number): string;
};
function isHydratable(obj: any): obj is { [Hydratable]: true };
const Hydratable: unique symbol;Testing utilities for creating component fixtures, managing async operations, and integration testing.
function fixture<T extends HTMLElement = HTMLElement>(
nameOrMarkupOrTemplate: string | ViewTemplate,
options?: FixtureOptions
): Promise<Fixture<T>>;
function uniqueElementName(): string;
function timeout(duration: number): Promise<void>;
interface Fixture<T extends HTMLElement = HTMLElement> {
document: Document;
template: ViewTemplate;
element: T;
parent: HTMLElement;
connect(): Promise<void>;
disconnect(): Promise<void>;
}DOM utilities and component orchestration for advanced scenarios involving Shadow DOM navigation and view behavior management.
function composedParent<T extends HTMLElement>(element: T): HTMLElement | null;
function composedContains(reference: HTMLElement, test: HTMLElement): boolean;
class UnobservableMutationObserver extends MutationObserver {
constructor(callback: MutationCallback);
observe(target: Node, options?: MutationObserverInit): void;
unobserve(target: Node): void;
}
const ViewBehaviorOrchestrator: {
create<TSource = any, TParent = any>(source: TSource): ViewBehaviorOrchestrator<TSource, TParent>;
};interface Constructable<T = {}> {
new (...args: any[]): T;
}
interface Disposable {
dispose(): void;
}
interface ExecutionContext<TParent = any> {
index: number;
length: number;
parent: TParent;
parentContext: ExecutionContext<TParent>;
}
type Expression<TReturn = any, TSource = any, TParent = any> =
| ((source: TSource, context: ExecutionContext<TParent>) => TReturn)
| string;
interface Subscriber {
handleChange(source: any, args: any): void;
}
interface ViewTemplate<TSource = any, TParent = any> {
create(host?: Element): HTMLView<TSource, TParent>;
render(source: TSource, host: Element | string, hostBindingTarget?: Element): HTMLView<TSource, TParent>;
}
interface HTMLView<TSource = any, TParent = any> {
firstChild: Node | null;
lastChild: Node | null;
bind(source: TSource, context?: ExecutionContext<TParent>): void;
unbind(): void;
appendTo(parent: Node): void;
removeFrom(parent: Node): void;
}
interface ElementStyles {
behaviors?: HostBehavior[];
addStylesTo(target: StyleTarget): void;
removeStylesFrom(target: StyleTarget): void;
}
interface Binding<TSource = any, TReturn = any, TParent = any> {
evaluate(source: TSource, context: ExecutionContext<TParent>): TReturn;
}
type Key = string | object | Interface | Constructable | null;
type Resolved<K> = K extends Constructable<infer T> ? T : K extends Interface<infer T> ? T : K;
interface Interface<T = any> {
readonly name: string;
readonly $isInterface: true;
}