{"id":19856850,"url":"https://github.com/polymer/polymer-decorators","last_synced_at":"2025-05-16T18:05:27.352Z","repository":{"id":24930263,"uuid":"87834549","full_name":"Polymer/polymer-decorators","owner":"Polymer","description":"TypeScript decorators for Polymer.","archived":false,"fork":false,"pushed_at":"2024-11-04T23:27:27.000Z","size":1625,"stargazers_count":93,"open_issues_count":27,"forks_count":23,"subscribers_count":33,"default_branch":"master","last_synced_at":"2025-04-03T17:11:21.287Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Polymer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-10T16:43:07.000Z","updated_at":"2024-11-04T23:27:29.000Z","dependencies_parsed_at":"2024-06-18T15:22:20.676Z","dependency_job_id":"c04b15be-5c8b-47f6-b4a1-ed1c32494407","html_url":"https://github.com/Polymer/polymer-decorators","commit_stats":{"total_commits":117,"total_committers":14,"mean_commits":8.357142857142858,"dds":0.2136752136752137,"last_synced_commit":"4e1b54e965f26eb65ee8a8a880bc010a878962ce"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polymer%2Fpolymer-decorators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polymer%2Fpolymer-decorators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polymer%2Fpolymer-decorators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polymer%2Fpolymer-decorators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Polymer","download_url":"https://codeload.github.com/Polymer/polymer-decorators/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248597717,"owners_count":21130929,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T14:16:45.166Z","updated_at":"2025-04-12T16:38:10.700Z","avatar_url":"https://github.com/Polymer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![NPM version](http://img.shields.io/npm/v/@polymer/decorators.svg)](https://www.npmjs.com/package/@polymer/decorators)\n\n\u003e [!WARNING]\n\u003e These decorators assume the TypeScript experimental decorator API. The TypeScript team [plans](https://github.com/microsoft/TypeScript/issues/45995#issuecomment-2291606365) to deprecate it in v6.0 of the TypeScript compiler, and remove it in v6.5. Based on their three-month release cadence, v6.5 will be released around the end of 2026.\n\u003e\n\u003e Existing deployments will work indefinitely, and code can still be built with older versions of the TypeScript compiler.\n\u003e\n\u003e Given the low usage of these decorators (~0.5% of Polymer's usage), we do not plan to update this library to use the standard decorators API. If this is a blocker for you, please let us know by opening an issue or reaching out on [the Lit Discord](https://lit.dev/discord/).\n\u003e\n\u003e For those codebases that use these decorators and plan to continue to update their TypeScript compiler in 2027 and beyond, we'd recommend removing the decorators from your TypeScript code and [writing it similarly to how you would write it in JavaScript](#do-i-need-this-library-to-use-polymer-and-typescript).\n\n# polymer-decorators\n\nA library of [decorators](https://github.com/tc39/proposal-decorators) to help\nyou write [web\ncomponents](https://developer.mozilla.org/en-US/docs/Web/Web_Components) with\n[Polymer](https://www.polymer-project.org/) in\n[TypeScript](https://www.typescriptlang.org/) in a type safe and convenient\nway, like this:\n\n```ts\nimport {PolymerElement} from '@polymer/polymer';\nimport {customElement, property} from '@polymer/decorators';\n\n@customElement('my-element')\nclass MyElement extends PolymerElement {\n\n  @property({type: String})\n  myProperty: string = 'foo';\n}\n```\n\n## Contents\n\n- [Installation](#installation)\n- [Decorator reference](#decorator-reference)\n   - [@customElement](#customelementtagname-string)\n   - [@property](#propertyoptions-propertyobjects)\n   - [@computed](#computedtargets-string)\n   - [@observe](#observetargets-string)\n   - [@query](#queryselector-string)\n   - [@queryAll](#queryallselector-string)\n   - [@listen](#listeneventname-string-target-stringeventtarget)\n- [FAQ](#faq)\n   - [Do I need this library to use Polymer and Typescript?](#do-i-need-this-library-to-use-polymer-and-typescript)\n   - [What are the performance costs?](#what-are-the-performance-costs)\n   - [Does it work with previous versions of Polymer?](#does-it-work-with-previous-versions-of-polymer)\n   - [What happened to Metadata Reflection support?](#what-happened-to-metadata-reflection-support)\n\n\n## Installation\n\n1. Install the decorators with NPM.\n\n   ```sh\n   npm install --save @polymer/decorators\n   ```\n\n2. Import decorators in your component definitions:\n\n   ```js\n   import {customElement, property} from '@polymer/decorators';\n   ```\n\n3. Enable the\n   [`experimentalDecorators`](https://www.typescriptlang.org/docs/handbook/decorators.html#metadata)\n   TypeScript compiler setting. Use the `--experimentalDecorators` flag, or\n   update your `tsconfig.json` to include:\n\n   ```js\n   {\n     \"compilerOptions\": {\n       \"experimentalDecorators\": true\n     }\n   }\n   ```\n\n## Decorator reference\n\n### `@customElement(tagname?: string)`\n\nDefine a custom element.\n\nIf `tagname` is provided, it will be used as the custom element name, and will\nbe assigned to the class static `is` property. If `tagname` is omitted, the\nstatic `is` property of the class will be used instead. If neither exist, or if\nboth exist but have different values (except in the case that the `is` property\nis not an own-property of the class), an exception is thrown.\n\nThis decorator automatically calls\n[`customElements.define()`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define)\nwith your class, so you should not include your own call to that function.\n\n```ts\n@customElement('my-element')\nclass MyElement extends PolymerElement {\n  ...\n}\n```\n\n### `@property(options?: PropertyObjects)`\nDefine a Polymer property.\n\n`options` is a [Polymer property\noptions](https://www.polymer-project.org/3.0/docs/devguide/properties) object.\nAll standard options are supported, except for `value`; use a property\ninitializer instead. `type` is required, and must be one of the Polymer property\nconstructor types (`String`, `Object`, etc.).\n\n```ts\n@property({type: String, notify: true})\nfoo: string = 'hello';\n```\n\n### `@computed(...targets: string[])`\n\nDefine a [computed\nproperty](https://www.polymer-project.org/3.0/docs/devguide/observers#computed-properties).\n\nThis decorator must be applied to a\n[getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get),\nand it must not have an associated setter.\n\nBe sure to only read properties that you have declared as dependencies in the\ncomputed property definition, otherwise the computed property will not update\nas expected.\n\n```ts\n@computed('foo', 'bar')\nget fooBar() {\n  return this.foo + this.bar;\n}\n```\n\nTo define a computed property with more complex dependency expressions for\nwhich you may want to receive change values as arguments (e.g. sub-properties,\nsplices, wildcards, etc.), or to set additional property options, define a\nstandard property and set its `computed` option.\n\n```ts\n@property({computed: 'computeBaz(foo.*)', reflectToAttribute: true, type: String})\nbaz: string;\n\nprivate computeBaz(fooChangeRecord: object) {\n  ...\n}\n```\n\n### `@observe(...targets: string[])`\n\nDefine a [complex property\nobserver](https://www.polymer-project.org/3.0/docs/devguide/observers#complex-observers).\n\n`targets` can be a single dependency expression, or an array of them. All\nobserver dependency syntaxes are supported (property names, sub-properties,\nsplices, wildcards, etc.).\n\n```ts\n@observe('foo', 'bar')\nprivate fooBarChanged(newFoo: string, newBar: string) {\n  console.log(`foo is now: ${newFoo}, bar is now: ${newBar}`);\n}\n\n@observe('baz.*')\nprivate bazChanged(changeRecord: object) {\n  console.log('baz changed deeply');\n}\n```\n\nTo define a [simple property\nobserver](https://www.polymer-project.org/3.0/docs/devguide/observers#simple-observers),\nwhich receives both the old and new values, set the `observer` option on the\nproperty you want to observe to the observer name or (preferably) function\nreference.\n\n```ts\n@property({observer: MyElement.prototype.bazChanged, type: String})\nbaz: string;\n\nprivate bazChanged(newValue: string, oldValue: string) {\n  console.log(`baz was: ${oldValue}, and is now: ${newValue}`);\n}\n```\n\n### `@query(selector: string)`\n\nReplace this property with a getter that calls\n[`querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector)\non the shadow root with the given `selector`. Use this to get a typed handle to\na node in your template.\n\n```ts\n@query('my-widget')\nwidget: MyWidgetElement;\n```\n\n### `@queryAll(selector: string)`\n\nReplace this property with a getter that calls\n[`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll)\non the shadow root with the given `selector`. Use this to get a typed handle to\na set of nodes in your template.\n\n```ts\n@queryAll('my-widget')\nwidgets: NodeListOf\u003cMyWidgetElement\u003e\n```\n\n### `@listen(eventName: string, target: string|EventTarget)`\n\nAdd an event listener for `eventName` on `target`. `target` can be an object\nreference, or the string id of an element in the shadow root. The method must\nmatch the signature `(e: Event) =\u003e void`, and must have `public` visibility.\n\nNote that a `target` referenced by id must be defined statically in the\ntop-level element template (e.g. not in a `\u003cdom-if\u003e`), because the `$` id map\nis used to find the target upon `ready()`.\n\nTo use `@listen`, your element must apply the\n[`DeclarativeEventListeners`](https://github.com/Polymer/polymer-decorators/blob/master/src/declarative-event-listeners.ts)\nmixin, which is supplied with this package.\n\n```ts\nimport {DeclarativeEventListeners} from '@polymer/decorators/lib/declarative-event-listeners.js';\n\nclass MyElement extends DeclarativeEventListeners(PolymerElement) {\n  @listen('scroll', document)\n  onDocumentScroll(event: Event) {\n    this.scratchChalkboard();\n  }\n}\n```\n\nNote that to listen for Polymer [gesture\nevents](https://www.polymer-project.org/3.0/docs/devguide/gesture-events) such\nas `tap` and `track`, your element must also apply the\n[`GestureEventListeners`](https://github.com/Polymer/polymer/blob/master/lib/mixins/gesture-event-listeners.js)\nmixin, which is supplied with Polymer.\n\n```ts\nimport {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';\nimport {DeclarativeEventListeners} from '@polymer/decorators/lib/declarative-event-listeners.js';\n\nclass MyElement extends\n    GestureEventListeners(\n    DeclarativeEventListeners(\n    PolymerElement)) {\n\n  @listen('tap', 'red-button')\n  onTapRedButton(event: Event) {\n    this.launchMissile();\n  }\n}\n```\n\n## FAQ\n\n### Do I need this library to use Polymer and TypeScript?\nNo, you can also use Polymer and TypeScript without any additional libraries.\nPolymer 3.0 ships with declarations to let you use the API with TypeScript\ndirectly.  The advantage of using these decorators are additional type safety\nand convenience. For simple elements and applications, it may be preferable to\nuse the vanilla Polymer API, like this:\n\n```ts\nimport {PolymerElement, html} from '@polymer/polymer';\n\nclass MyElement extends PolymerElement {\n  static get properties() {\n    return {\n      myProperty: String\n    };\n  };\n\n  static get template() {\n    return html`\u003cp\u003eHello World\u003c/p\u003e`;\n  }\n\n  myProperty: string = 'foo';\n}\n\ncustomElements.define('my-element', MyElement);\n```\n\n### What are the performance costs?\nThe additional JavaScript served for this library is approximately 2KB gzipped\n(0.6KB minified + gzipped). Benchmarks are not currently available, but we\nexpect minor performance costs. The library generally works by building standard\nPolymer property definitions at element definition time, so performance costs\nshould be seen at application startup.\n\n### Does it work with previous versions of Polymer?\nAn earlier version of this library can be used with Polymer 2.0, and installed\nwith Bower. See the\n[`2.x`](https://github.com/Polymer/polymer-decorators/tree/2.x) branch.\n\nThis library is not compatible with Polymer 1.0 or earlier, because it depends\non the ES6 class-based component definition style introduced in Polymer 2.0.\nCommunity-maintained TypeScript decorator options for Polymer 1.0 include\n[nippur72/PolymerTS](https://github.com/nippur72/PolymerTS) and\n[Cu3PO42/polymer-decorators](https://github.com/Cu3PO42/polymer-decorators).\n\n### What happened to Metadata Reflection support?\nSupport for the [Metadata Reflection\nAPI](https://rbuckton.github.io/reflect-metadata/) was removed in version\n`3.0.0`. This was done primarily because the type metadata emitted by TypeScript\nis often incorrect for our purpose (e.g. `string|undefined` produces `Object`\ninstead of `String`), leading to unexpected bugs. Additionally, the required\npolyfill is fairly large (7KB gzipped), and standardization of the proposal does\nnot currently appear to be progressing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolymer%2Fpolymer-decorators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolymer%2Fpolymer-decorators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolymer%2Fpolymer-decorators/lists"}