UNPKG

@lit/reactive-element

Version:

A simple low level base class for creating fast, lightweight web components

92 lines 3.68 kB
/** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const standardProperty = (options, element) => { // When decorating an accessor, pass it through and add property metadata. // Note, the `hasOwnProperty` check in `createProperty` ensures we don't // stomp over the user's accessor. if (element.kind === 'method' && element.descriptor && !('value' in element.descriptor)) { return { ...element, finisher(clazz) { clazz.createProperty(element.key, options); }, }; } else { // createProperty() takes care of defining the property, but we still // must return some kind of descriptor, so return a descriptor for an // unused prototype field. The finisher calls createProperty(). return { kind: 'field', key: Symbol(), placement: 'own', descriptor: {}, // store the original key so subsequent decorators have access to it. originalKey: element.key, // When @babel/plugin-proposal-decorators implements initializers, // do this instead of the initializer below. See: // https://github.com/babel/babel/issues/9260 extras: [ // { // kind: 'initializer', // placement: 'own', // initializer: descriptor.initializer, // } // ], initializer() { if (typeof element.initializer === 'function') { this[element.key] = element.initializer.call(this); } }, finisher(clazz) { clazz.createProperty(element.key, options); }, }; } }; const legacyProperty = (options, proto, name) => { proto.constructor.createProperty(name, options); }; /** * A property decorator which creates a reactive property that reflects a * corresponding attribute value. When a decorated property is set * the element will update and render. A {@linkcode PropertyDeclaration} may * optionally be supplied to configure property features. * * This decorator should only be used for public fields. As public fields, * properties 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 {@linkcode state} decorator. * * 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 decorated via the {@linkcode state} decorator should be used. When * needed, state properties can be initialized via public properties to * facilitate complex interactions. * * ```ts * class MyElement { * @property({ type: Boolean }) * clicked = false; * } * ``` * @category Decorator * @ExportDecoratedItems */ export function property(options) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (protoOrDescriptor, name) => name !== undefined ? legacyProperty(options, protoOrDescriptor, name) : standardProperty(options, protoOrDescriptor); } //# sourceMappingURL=property.js.map