{"version":3,"file":"property.js","sources":["../../../src/decorators/property.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/*\n * IMPORTANT: For compatibility with tsickle and the Closure JS compiler, all\n * property decorators (but not class decorators) in this file that have\n * an @ExportDecoratedItems annotation must be defined as a regular function,\n * not an arrow function.\n */\n\nimport {\n  type PropertyDeclaration,\n  type ReactiveElement,\n  defaultConverter,\n  notEqual,\n} from '../reactive-element.js';\nimport type {Interface} from './base.js';\n\nconst DEV_MODE = true;\n\nlet issueWarning: (code: string, warning: string) => void;\n\nif (DEV_MODE) {\n  // Ensure warnings are issued only 1x, even if multiple versions of Lit\n  // are loaded.\n  globalThis.litIssuedWarnings ??= new Set();\n\n  /**\n   * Issue a warning if we haven't already, based either on `code` or `warning`.\n   * Warnings are disabled automatically only by `warning`; disabling via `code`\n   * can be done by users.\n   */\n  issueWarning = (code: string, warning: string) => {\n    warning += ` See https://lit.dev/msg/${code} for more information.`;\n    if (\n      !globalThis.litIssuedWarnings!.has(warning) &&\n      !globalThis.litIssuedWarnings!.has(code)\n    ) {\n      console.warn(warning);\n      globalThis.litIssuedWarnings!.add(warning);\n    }\n  };\n}\n\n// Overloads for property decorator so that TypeScript can infer the correct\n// return type when a decorator is used as an accessor decorator or a setter\n// decorator.\nexport type PropertyDecorator = {\n  // accessor decorator signature\n  <C extends Interface<ReactiveElement>, V>(\n    target: ClassAccessorDecoratorTarget<C, V>,\n    context: ClassAccessorDecoratorContext<C, V>\n  ): ClassAccessorDecoratorResult<C, V>;\n\n  // setter decorator signature\n  <C extends Interface<ReactiveElement>, V>(\n    target: (value: V) => void,\n    context: ClassSetterDecoratorContext<C, V>\n  ): (this: C, value: V) => void;\n\n  // legacy decorator signature\n  (\n    protoOrDescriptor: Object,\n    name: PropertyKey,\n    descriptor?: PropertyDescriptor\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  ): any;\n};\n\nconst legacyProperty = (\n  options: PropertyDeclaration | undefined,\n  proto: Object,\n  name: PropertyKey\n) => {\n  const hasOwnProperty = proto.hasOwnProperty(name);\n  (proto.constructor as typeof ReactiveElement).createProperty(name, options);\n  // For accessors (which have a descriptor on the prototype) we need to\n  // return a descriptor, otherwise TypeScript overwrites the descriptor we\n  // define in createProperty() with the original descriptor. We don't do this\n  // for fields, which don't have a descriptor, because this could overwrite\n  // descriptor defined by other decorators.\n  return hasOwnProperty\n    ? Object.getOwnPropertyDescriptor(proto, name)\n    : undefined;\n};\n\n// This is duplicated from a similar variable in reactive-element.ts, but\n// actually makes sense to have this default defined with the decorator, so\n// that different decorators could have different defaults.\nconst defaultPropertyDeclaration: PropertyDeclaration = {\n  attribute: true,\n  type: String,\n  converter: defaultConverter,\n  reflect: false,\n  hasChanged: notEqual,\n};\n\n// Temporary type, until google3 is on TypeScript 5.2\ntype StandardPropertyContext<C, V> = (\n  | ClassAccessorDecoratorContext<C, V>\n  | ClassSetterDecoratorContext<C, V>\n) & {metadata: object};\n\n/**\n * Wraps a class accessor or setter so that `requestUpdate()` is called with the\n * property name and old value when the accessor is set.\n */\nexport const standardProperty = <C extends Interface<ReactiveElement>, V>(\n  options: PropertyDeclaration = defaultPropertyDeclaration,\n  target: ClassAccessorDecoratorTarget<C, V> | ((value: V) => void),\n  context: StandardPropertyContext<C, V>\n): ClassAccessorDecoratorResult<C, V> | ((this: C, value: V) => void) => {\n  const {kind, metadata} = context;\n\n  if (DEV_MODE && metadata == null) {\n    issueWarning(\n      'missing-class-metadata',\n      `The class ${target} is missing decorator metadata. This ` +\n        `could mean that you're using a compiler that supports decorators ` +\n        `but doesn't support decorator metadata, such as TypeScript 5.1. ` +\n        `Please update your compiler.`\n    );\n  }\n\n  // Store the property options\n  let properties = globalThis.litPropertyMetadata.get(metadata);\n  if (properties === undefined) {\n    globalThis.litPropertyMetadata.set(metadata, (properties = new Map()));\n  }\n  if (kind === 'setter') {\n    options = Object.create(options);\n    options.wrapped = true;\n  }\n  properties.set(context.name, options);\n\n  if (kind === 'accessor') {\n    // Standard decorators cannot dynamically modify the class, so we can't\n    // replace a field with accessors. The user must use the new `accessor`\n    // keyword instead.\n    const {name} = context;\n    return {\n      set(this: ReactiveElement, v: V) {\n        const oldValue = (\n          target as ClassAccessorDecoratorTarget<C, V>\n        ).get.call(this as unknown as C);\n        (target as ClassAccessorDecoratorTarget<C, V>).set.call(\n          this as unknown as C,\n          v\n        );\n        this.requestUpdate(name, oldValue, options, true, v);\n      },\n      init(this: ReactiveElement, v: V): V {\n        if (v !== undefined) {\n          this._$changeProperty(name, undefined, options, v);\n        }\n        return v;\n      },\n    } as unknown as ClassAccessorDecoratorResult<C, V>;\n  } else if (kind === 'setter') {\n    const {name} = context;\n    return function (this: ReactiveElement, value: V) {\n      const oldValue = this[name as keyof ReactiveElement];\n      (target as (value: V) => void).call(this, value);\n      this.requestUpdate(name, oldValue, options, true, value);\n    } as unknown as (this: C, value: V) => void;\n  }\n  throw new Error(`Unsupported decorator location: ${kind}`);\n};\n\n/**\n * A class field or accessor decorator which creates a reactive property that\n * reflects a corresponding attribute value. When a decorated property is set\n * the element will update and render. A {@linkcode PropertyDeclaration} may\n * optionally be supplied to configure property features.\n *\n * This decorator should only be used for public fields. As public fields,\n * properties should be considered as primarily settable by element users,\n * either via attribute or the property itself.\n *\n * Generally, properties that are changed by the element should be private or\n * protected fields and should use the {@linkcode state} decorator.\n *\n * However, sometimes element code does need to set a public property. This\n * should typically only be done in response to user interaction, and an event\n * should be fired informing the user; for example, a checkbox sets its\n * `checked` property when clicked and fires a `changed` event. Mutating public\n * properties should typically not be done for non-primitive (object or array)\n * properties. In other cases when an element needs to manage state, a private\n * property decorated via the {@linkcode state} decorator should be used. When\n * needed, state properties can be initialized via public properties to\n * facilitate complex interactions.\n *\n * ```ts\n * class MyElement {\n *   @property({ type: Boolean })\n *   clicked = false;\n * }\n * ```\n * @category Decorator\n * @ExportDecoratedItems\n */\nexport function property(options?: PropertyDeclaration): PropertyDecorator {\n  return <C extends Interface<ReactiveElement>, V>(\n    protoOrTarget:\n      | object\n      | ClassAccessorDecoratorTarget<C, V>\n      | ((value: V) => void),\n    nameOrContext:\n      | PropertyKey\n      | ClassAccessorDecoratorContext<C, V>\n      | ClassSetterDecoratorContext<C, V>\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  ): any => {\n    return (\n      typeof nameOrContext === 'object'\n        ? standardProperty<C, V>(\n            options,\n            protoOrTarget as\n              | ClassAccessorDecoratorTarget<C, V>\n              | ((value: V) => void),\n            nameOrContext as StandardPropertyContext<C, V>\n          )\n        : legacyProperty(\n            options,\n            protoOrTarget as Object,\n            nameOrContext as PropertyKey\n          )\n    ) as PropertyDecorator;\n  };\n}\n"],"names":[],"mappings":"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"}