/** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ /** * Use this module if you want to create your own base class extending * {@link ReactiveElement}. * @packageDocumentation */ import { CSSResultGroup, CSSResultOrNative } from './css-tag.js'; import type { ReactiveController, ReactiveControllerHost } from './reactive-controller.js'; export * from './css-tag.js'; export type { ReactiveController, ReactiveControllerHost, } from './reactive-controller.js'; /** * Contains types that are part of the unstable debug API. * * Everything in this API is not stable and may change or be removed in the future, * even on patch releases. */ export declare namespace ReactiveUnstable { /** * When Lit is running in dev mode and `window.emitLitDebugLogEvents` is true, * we will emit 'lit-debug' events to window, with live details about the update and render * lifecycle. These can be useful for writing debug tooling and visualizations. * * Please be aware that running with window.emitLitDebugLogEvents has performance overhead, * making certain operations that are normally very cheap (like a no-op render) much slower, * because we must copy data and dispatch events. */ namespace DebugLog { type Entry = Update; interface Update { kind: 'update'; } } } /** * Converts property values to and from attribute values. */ export interface ComplexAttributeConverter { /** * Called to convert an attribute value to a property * value. */ fromAttribute?(value: string | null, type?: TypeHint): Type; /** * Called to convert a property value to an attribute * value. * * It returns unknown instead of string, to be compatible with * https://github.com/WICG/trusted-types (and similar efforts). */ toAttribute?(value: Type, type?: TypeHint): unknown; } declare type AttributeConverter = ComplexAttributeConverter | ((value: string | null, type?: TypeHint) => Type); /** * Defines options for a property accessor. */ export interface PropertyDeclaration { /** * When set to `true`, indicates the property is internal private state. The * property should not be set by users. When using TypeScript, this property * should be marked as `private` or `protected`, and it is also a common * practice to use a leading `_` in the name. The property is not added to * `observedAttributes`. */ readonly state?: boolean; /** * Indicates how and whether the property becomes an observed attribute. * If the value is `false`, the property is not added to `observedAttributes`. * If true or absent, the lowercased property name is observed (e.g. `fooBar` * becomes `foobar`). If a string, the string value is observed (e.g * `attribute: 'foo-bar'`). */ readonly attribute?: boolean | string; /** * Indicates the type of the property. This is used only as a hint for the * `converter` to determine how to convert the attribute * to/from a property. */ readonly type?: TypeHint; /** * Indicates how to convert the attribute to/from a property. If this value * is a function, it is used to convert the attribute value a the property * value. If it's an object, it can have keys for `fromAttribute` and * `toAttribute`. If no `toAttribute` function is provided and * `reflect` is set to `true`, the property value is set directly to the * attribute. A default `converter` is used if none is provided; it supports * `Boolean`, `String`, `Number`, `Object`, and `Array`. Note, * when a property changes and the converter is used to update the attribute, * the property is never updated again as a result of the attribute changing, * and vice versa. */ readonly converter?: AttributeConverter; /** * Indicates if the property should reflect to an attribute. * If `true`, when the property is set, the attribute is set using the * attribute name determined according to the rules for the `attribute` * property option and the value of the property converted using the rules * from the `converter` property option. */ readonly reflect?: boolean; /** * A function that indicates if a property should be considered changed when * it is set. The function should take the `newValue` and `oldValue` and * return `true` if an update should be requested. */ hasChanged?(value: Type, oldValue: Type): boolean; /** * Indicates whether an accessor will be created for this property. By * default, an accessor will be generated for this property that requests an * update when set. If this flag is `true`, no accessor will be created, and * it will be the user's responsibility to call * `this.requestUpdate(propertyName, oldValue)` to request an update when * the property changes. */ readonly noAccessor?: boolean; } /** * Map of properties to PropertyDeclaration options. For each property an * accessor is made, and the property is processed according to the * PropertyDeclaration options. */ export interface PropertyDeclarations { readonly [key: string]: PropertyDeclaration; } declare type PropertyDeclarationMap = Map; /** * A Map of property keys to values. * * Takes an optional type parameter T, which when specified as a non-any, * non-unknown type, will make the Map more strongly-typed, associating the map * keys with their corresponding value type on T. * * Use `PropertyValues` when overriding ReactiveElement.update() and * other lifecycle methods in order to get stronger type-checking on keys * and values. */ export declare type PropertyValues = T extends object ? PropertyValueMap : Map; /** * Do not use, instead prefer {@linkcode PropertyValues}. */ export interface PropertyValueMap extends Map { get(k: K): T[K]; set(key: K, value: T[K]): this; has(k: K): boolean; delete(k: K): boolean; } export declare const defaultConverter: ComplexAttributeConverter; export interface HasChanged { (value: unknown, old: unknown): boolean; } /** * Change function that returns true if `value` is different from `oldValue`. * This method is used as the default for a property's `hasChanged` function. */ export declare const notEqual: HasChanged; /** * The Closure JS Compiler doesn't currently have good support for static * property semantics where "this" is dynamic (e.g. * https://github.com/google/closure-compiler/issues/3177 and others) so we use * this hack to bypass any rewriting by the compiler. */ declare const finalized = "finalized"; /** * A string representing one of the supported dev mode warning categories. */ export declare type WarningKind = 'change-in-update' | 'migration'; export declare type Initializer = (element: ReactiveElement) => void; /** * Base element class which manages element properties and attributes. When * properties change, the `update` method is asynchronously called. This method * should be supplied by subclassers to render updates as desired. * @noInheritDoc */ export declare abstract class ReactiveElement extends HTMLElement implements ReactiveControllerHost { /** * Read or set all the enabled warning categories for this class. * * This property is only used in development builds. * * @nocollapse * @category dev-mode */ static enabledWarnings?: WarningKind[]; /** * Enable the given warning category for this class. * * This method only exists in development builds, so it should be accessed * with a guard like: * * ```ts * // Enable for all ReactiveElement subclasses * ReactiveElement.enableWarning?.('migration'); * * // Enable for only MyElement and subclasses * MyElement.enableWarning?.('migration'); * ``` * * @nocollapse * @category dev-mode */ static enableWarning?: (warningKind: WarningKind) => void; /** * Disable the given warning category for this class. * * This method only exists in development builds, so it should be accessed * with a guard like: * * ```ts * // Disable for all ReactiveElement subclasses * ReactiveElement.disableWarning?.('migration'); * * // Disable for only MyElement and subclasses * MyElement.disableWarning?.('migration'); * ``` * * @nocollapse * @category dev-mode */ static disableWarning?: (warningKind: WarningKind) => void; /** * Adds an initializer function to the class that is called during instance * construction. * * This is useful for code that runs against a `ReactiveElement` * subclass, such as a decorator, that needs to do work for each * instance, such as setting up a `ReactiveController`. * * ```ts * const myDecorator = (target: typeof ReactiveElement, key: string) => { * target.addInitializer((instance: ReactiveElement) => { * // This is run during construction of the element * new MyController(instance); * }); * } * ``` * * Decorating a field will then cause each instance to run an initializer * that adds a controller: * * ```ts * class MyElement extends LitElement { * @myDecorator foo; * } * ``` * * Initializers are stored per-constructor. Adding an initializer to a * subclass does not add it to a superclass. Since initializers are run in * constructors, initializers will run in order of the class hierarchy, * starting with superclasses and progressing to the instance's class. * * @nocollapse */ static addInitializer(initializer: Initializer): void; static _initializers?: Initializer[]; /** * Maps attribute names to properties; for example `foobar` attribute to * `fooBar` property. Created lazily on user subclasses when finalizing the * class. * @nocollapse */ private static __attributeToPropertyMap; /** * Marks class as having finished creating properties. */ protected static [finalized]: boolean; /** * Memoized list of all element properties, including any superclass properties. * Created lazily on user subclasses when finalizing the class. * @nocollapse * @category properties */ static elementProperties: PropertyDeclarationMap; /** * User-supplied object that maps property names to `PropertyDeclaration` * objects containing options for configuring reactive properties. When * a reactive property is set the element will update and render. * * By default properties are public fields, and as such, they should be * considered as primarily settable by element users, either via attribute or * the property itself. * * Generally, properties that are changed by the element should be private or * protected fields and should use the `state: true` option. Properties * marked as `state` do not reflect from the corresponding attribute * * However, sometimes element code does need to set a public property. This * should typically only be done in response to user interaction, and an event * should be fired informing the user; for example, a checkbox sets its * `checked` property when clicked and fires a `changed` event. Mutating * public properties should typically not be done for non-primitive (object or * array) properties. In other cases when an element needs to manage state, a * private property set with the `state: true` option should be used. When * needed, state properties can be initialized via public properties to * facilitate complex interactions. * @nocollapse * @category properties */ static properties: PropertyDeclarations; /** * Memoized list of all element styles. * Created lazily on user subclasses when finalizing the class. * @nocollapse * @category styles */ static elementStyles: Array; /** * Array of styles to apply to the element. The styles should be defined * using the {@linkcode css} tag function, via constructible stylesheets, or * imported from native CSS module scripts. * * Note on Content Security Policy: * * Element styles are implemented with `