Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 8x 8x 6x 3x 3x 3x 3x 3x 6x 6x 6x 4x 6x 6x 6x 6x 6x 6x 6x | import { Mutable, TypeOf } from '@sgrud/core'; import { Component } from './component'; /** * {@link Component} prototype property decorator factory. Applying the * **Attribute** decorator to a property of a {@link Component} binds the * decorated property to the corresponding **Attribute** of the respective * {@link Component}. This implies that the **Attribute** `name` is appended to * the {@link Component.observedAttributes} array of the {@link Component} and * the decorated property is replaced with a getter and setter deferring those * operations to the **Attribute**. If no `name` supplied, the name of the * decorated property will be used instead. Further, if both, a parameter * initializer and an initial **Attribute** value are supplied, the * **Attribute** value takes precedence. * * @param name - The {@link Component} **Attribute** `name`. * @returns A {@link Component} prototype property decorator. * * @example * Bind a property to an **Attribute**: * ```tsx * import { Attribute, Component } from '@sgrud/shell'; * * declare global { * interface HTMLElementTagNameMap { * 'example-component': ExampleComponent; * } * } * * @Component('example-component') * export class ExampleComponent extends HTMLElement implements Component { * * @Attribute() * public field?: string; * * public get template(): JSX.Element { * return <span>Attribute value: {this.field}</span>; * } * * } * ``` * * @see {@link Component} */ export function Attribute(name?: string) { /** * @param prototype - The {@link Component} `prototype` to be decorated. * @param propertyKey - The {@link Component} property to be decorated. */ return function(prototype: Component, propertyKey: PropertyKey): void { // eslint-disable-next-line @typescript-eslint/unbound-method const connectedCallback = prototype.connectedCallback; const key = name || propertyKey as string; prototype.connectedCallback = function(this: Component): void { Object.defineProperty(this, propertyKey, { enumerable: true, get(this: Component): string | undefined { return this.getAttribute(key) ?? undefined; }, set(this: Component, value: string): void { if (TypeOf.null(value) || TypeOf.undefined(value)) { this.removeAttribute(key); } else { this.setAttribute(key, value); } } }); return connectedCallback ? connectedCallback.call(this) : this.renderComponent?.(); }; ((prototype as Mutable<Component>).observedAttributes ||= []).push(key); }; } |