![38% of CISOs Fear They’re Not Moving Fast Enough on AI](https://cdn.sanity.io/images/cgdhsj6q/production/faa0bc28df98f791e11263f8239b34207f84b86f-1024x1024.webp?w=400&fit=max&auto=format)
Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
org.webjars.bowergithub.polymer:polymer-decorators
Advanced tools
A library of decorators to help you write web components with Polymer in TypeScript in a type safe and convenient way, like this:
@customElement('my-element')
class MyElement extends Polymer.Element {
@property()
myProperty: string = 'foo';
}
Install the decorators with Bower (NPM support coming with Polymer 3.0):
bower install --save Polymer/polymer-decorators
Import the decorator library in your component definitions:
<link rel="import" href="/bower_components/polymer-decorators/polymer-decorators.html">
Include type declarations for Polymer (available as of version 2.4) and the
Polymer decorators in one your TypeScript source files. You can also add
them as sources in your tsconfig.json
with include
or files
.
/// <reference path="./bower_components/polymer/types/polymer-element.d.ts" />
/// <reference path="./bower_components/polymer-decorators/polymer-decorators.d.ts" />
Enable the
experimentalDecorators
TypeScript compiler setting. Use the --experimentalDecorators
flag, or
update your tsconfig.json
to include:
{
"compilerOptions": {
"experimentalDecorators": true
}
}
Optionally configure Metadata Reflection to define property types more concisely.
These decorator factory functions are defined on the Polymer.decorators
global namespace object. You can refer to them directly (e.g.
@Polymer.decorators.customElement()
), or you may prefer to assign them to
shorter variables:
const {customElement, property} = Polymer.decorators;
@customElement(tagname?: string)
Define a custom element.
If tagname
is provided, it will be used as the custom element name, and will
be assigned to the class static is
property. If tagname
is omitted, the
static is
property of the class will be used instead. If neither exist, or if
both exist but have different values (except in the case that the is
property
is not an own-property of the class), an exception is thrown.
This decorator automatically calls
customElements.define()
with your class, so you should not include your own call to that function.
@customElement('my-element')
class MyElement extends Polymer.Element {
...
}
@property(options?: PropertyObjects)
Define a Polymer property.
options
is a Polymer property
options object.
All standard options are supported, except for value
; use a property
initializer instead.
If the Metadata Reflection API is configured, the
type
option (which determines how Polymer de-serializes Element attributes
for this property) will be inferred from the TypeScript type and can be
omitted.
@property({type: String, notify: true})
foo: string = 'hello';
@computed(...targets: string[])
Define a computed property.
This decorator must be applied to a getter, and it must not have an associated setter.
Be sure to only read properties that you have declared as dependencies in the computed property definition, otherwise the computed property will not update as expected.
@computed('foo', 'bar')
get fooBar() {
return this.foo + this.bar;
}
⚠️ NOTE: Since TypeScript 2.7, any use of
@computed
with >1 dependencies will not compile unless the generic type parameter is specified explicitly (either with the element class as shown below, or simply withany
). See #48 for details.
For optional additional type saftey, pass your custom element class as a generic parameter. This allows TypeScript to check that all of your dependencies are valid properties.
@computed<MyElement>('foo', 'bar')
get fooBar() {
return this.foo + this.bar;
}
To set the type of a computed property when the Metadata Reflection API is not
available, apply an additional @property
decorator. Note that the @property
decorator should be applied first, but since decorators are executed bottom up,
it should be written second:
@computed<MyElement>('foo', 'bar')
@property({type: String})
get fooBar() {
To define a computed property with more complex dependency expressions for
which you may want to receive change values as arguments (e.g. sub-properties,
splices, wildcards, etc.), or to set additional property options, define a
standard property and set its computed
option.
@property({computed: 'computeBaz(foo.*)', reflectToAttribute: true})
baz: string;
private computeBaz(fooChangeRecord: object) {
...
}
@observe(...targets: string[])
Define a complex property observer.
targets
can be a single dependency expression, or an array of them. All
observer dependency syntaxes are supported (property names, sub-properties,
splices, wildcards, etc.).
@observe('foo', 'bar')
private fooBarChanged(newFoo: string, newBar: string) {
console.log(`foo is now: ${newFoo}, bar is now: ${newBar}`);
}
@observe('baz.*')
private bazChanged(changeRecord: object) {
console.log('baz changed deeply');
}
To define a simple property
observer,
which receives both the old and new values, set the observer
option on the
property you want to observe to the observer name or (preferably) function
reference.
@property({observer: MyElement.prototype.bazChanged})
baz: string;
private bazChanged(oldValue: string, newValue: string) {
console.log(`baz was: ${oldValue}, and is now: ${newValue}`);
}
@query(selector: string)
Replace this property with a getter that calls
querySelector
on the shadow root with the given selector
. Use this to get a typed handle to
a node in your template.
@query('my-widget')
widget: MyWidgetElement;
@queryAll(selector: string)
Replace this property with a getter that calls
querySelectorAll
on the shadow root with the given selector
. Use this to get a typed handle to
a set of nodes in your template.
@queryAll('my-widget')
widgets: NodeListOf<MyWidgetElement>
@listen(eventName: string, target: string|EventTarget)
Add an event listener for eventName
on target
. target
can be an object
reference, or the string id of an element in the shadow root.
Note that a target
referenced by id must be defined statically in the
top-level element template (e.g. not in a <dom-if>
), because the $
id map
is used to find the target upon ready()
.
To use @listen
, your element must apply the
DeclarativeEventListeners
mixin, which is supplied with this package.
/// <reference path="./bower_components/polymer-decorators/mixins/declarative-event-listeners.d.ts" />
class MyElement extends Polymer.DeclarativeEventListeners(Polymer.Element) {
@listen('scroll', document)
protected onDocumentScroll(event: Event) {
this.scratchChalkboard();
}
}
Note that to listen for Polymer gesture
events such
as tap
and track
, your element must also apply the
GestureEventListeners
mixin, which is supplied with Polymer.
class MyElement extends
Polymer.GestureEventListeners(
Polymer.DeclarativeEventListeners(
Polymer.Element)) {
@listen('tap', 'red-button')
protected onTapRedButton(event: Event) {
this.launchMissile();
}
}
To annotate your Polymer property types more concisely, you may configure experimental support for the Metadata Reflection API. Note that this API is not yet a formal ECMAScript proposal, but a polyfill is available, and TypeScript has experimental support.
Also note that the Metadata Reflection polyfill is 47 KB (7 KB gzipped), so be sure to consider strongly whether the cost of shipping this polyfill is worth the convenience for your project.
Without Metadata Reflection, the Polymer property type must be passed explicitly to the decorator factory, because type information is not otherwise available at runtime:
@property({type: String})
myProperty: string;
With Metadata Reflection, the TypeScript type annotation alone is sufficient, because the compiler will emit type information that the decorator can use to automatically set the Polymer property type:
@property()
myProperty: string;
To enable Metadata Reflection:
Enable the
emitDecoratorMetadata
TypeScript compiler setting. Use the --emitDecoratorMetadata
flag, or
update your tsconfig.json
to include:
{
"compilerOptions": {
"emitDecoratorMetadata": true
}
}
Install the Metadata Reflection API runtime polyfill from rbuckton/reflect-metadata:
bower install --save rbuckton/reflect-metadata
Load the polyfill at the top-level of your application, and in your tests:
<script src="/bower_components/reflect-metadata/Reflect.js"></script>
No, you can also use Polymer and TypeScript without additional client
libraries. As of Polymer 2.4, TypeScript type declarations are available in the
types/
directory. The
advantage of using these decorators are additional type safety and convenience.
For simple elements and applications, it may be preferable to use the vanilla
Polymer API, like this:
/// <reference path="./bower_components/polymer/types/polymer-element.d.ts" />
class MyElement extends Polymer.Element {
static is = 'my-element';
static properties = {
myProperty: {
type: String
}
};
myProperty: string = 'foo';
}
customElements.define(MyElement.is, MyElement);
The additional JavaScript served for this library is aproximately 8 KB (4 KB gzipped). Benchmarks are not currently available, but we expect minor performance costs. The library generally works by building standard Polymer property definitions at element definition time, so performance costs should be seen at application startup.
Not yet, but support is planned. See issue #10.
No, this library is not compatible with Polymer 1.0 or earlier, because it depends on the ES6 class-based component definition style introduced in Polymer 2.0. Community-maintained TypeScript decorator options for Polymer 1.0 include nippur72/PolymerTS and Cu3PO42/polymer-decorators.
FAQs
WebJar for polymer-decorators
We found that org.webjars.bowergithub.polymer:polymer-decorators demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.