Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Typescript decorators and type definitions for Polymer 2.0.

Notifications You must be signed in to change notification settings

LssPolymerElements/polymer2-ts

Repository files navigation

polymer2-ts -DEPRECATED

2-14-2018: With the recent annoucement of OFFICIAL support for Polymer Decorators and type definitions, we have decided to deprecate this project. Thanks to everyone for the contributions and support.


Build status

To install use: bower install --save polymer2-ts

Overview

Typescript decorators and type definitions for Polymer 2.0.

Available Behaviors

@customElement()

This class decorator will automatically add the is() getter and register your element.

@customElement("my-element")
class MyElement extends Polymer.Element {

}

@property(options?: PropertyOptions)

This property decorator will register your properties for you. Do not declare a properties getter. The type is inferred by the type declared in TypeScript. Assign defaults to the property directly.

class MyElement extends Polymer.Element {

    @property({ reflectToAttribute: true, notify: true })
    shape: string = "circle";
    
    @property()
    size: number = 60;    
}

Available PropertyOptions:

    notify?: boolean;
    reflectToAttribute?: boolean;
    readOnly?: boolean;

@listen(eventName: string, targetElem?: string)

This function decorator adds an event listener for the provided event name and calls back the function when the event is fired.

TypeScript:

class MyElement extends Polymer.Element {

 //Listen for tap events on the element with an id="submitButton"
  @listen("tap", "submitButton")
  submitButtonTapHandler(e){
      doSomething();
  }
  
  //Listen for all tap events on MyElement
  @listen("tap")
  tapHandler(e){
      doSomething();
  }
}

HTML:

<paper-button id="submitButton">Submit</paper-button>

@gestureListen(eventName: string, targetElem?: string)

This function decorator adds an polymer gesture listener for the provided event name and calls back the function when the event is fired.

IMPORTANT: When using this decorator your class must apply the gesture mix-in.

<link rel="import" href="polymer/lib/mixins/gesture-event-listeners.html">

<script>
    class TestEvent extends Polymer.GestureEventListeners(Polymer.Element) {
      ...
</script>

TypeScript:

class MyElement extends Polymer.Element {

 //Listen for tap events on the element with an id="submitButton"
  @listen("tap", "submitButton")
  submitButtonTapHandler(e){
      doSomething();
  }
  
  //Listen for all tap events on MyElement
  @listen("tap")
  tapHandler(e){
      doSomething();
  }
}

HTML:

<paper-button id="submitButton">Submit</paper-button>

computed(name: string)

This function decorator registers a computed property with the provided name. When one or more associated properties change, the computed property is updated.

TypeScript:
class MyElement extends Polymer.Element {
  @property( )
  numOne: number = 1;
    
  @property( )
  numTwo: number = 2;
        
  @computed('total')
  getSrc(numOne: number, numTwo: number) : number {
    return numOne + numTwo;
  }
}

HTML:

<h1>[[total]]</h1>

Result:

<h1>3</h1>

Recommended TypeScript Config

{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es2015",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "sourceMap": false,
    "lib": ["es2017", "dom"],
    "typeRoots": ["types"]
  },
  "exclude": [    
    "node_modules",
    "bower_components/reflect-metadata/"
  ]
}

Example

my-element.ts

@customElement("my-element")
class MyElement extends Polymer.Element {

    @property({ notify: true })
    personId: number = 44;

    @property()
    size: number = 60;

    @observe('size')
    _sizeChanged(size) {
        console.log("size changed to " + size);
    }
    
    @computed('src')
    _computePictureSrc(personId: number, size: number) {
        var baseUrl = this.isDev() ? "https://dev.example.com/" : "https://example.com/";
        return `${baseUrl}Picture(${personId})/Default.Picture(size=${size})`;
    }
}

my-element.html

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../polymer2-ts/polymer2-ts.html">

<dom-module id="my-element">
    <template>
        <style>
             :host {
                display: block;
            }            
        </style>
        <img src="{{src}}" style="height:[[size]]"></img>
    </template>
    <script type="text/javascript" src="my-element.js"></script>
</dom-module>