GithubHelp home page GithubHelp logo

tpluscode / twc Goto Github PK

View Code? Open in Web Editor NEW

This project forked from buslowicz/twc

0.0 2.0 0.0 218 KB

TypeScript based, boilerplate-less, Polymer toolbox friendly Polymer Modules

TypeScript 70.82% JavaScript 14.07% HTML 15.05% CSS 0.06%

twc's Introduction

Typed Web Components

Build Status

Typed Web Component brings you a boilerplate-less, TypeScript based way, to write native Polymer modules (Polymer toolbox friendly). The entire process is done in the design time, so no additional library needs to be added in the project.

Installation

npm install -g twc

Using

TWC comes with CLI and Stream consuming function (compatible with Gulp). For single components building, preferred method is to call twc command:

twc my-element.ts --out-dir dist

This will analyze the my-element.ts file and output my-element.d.ts and my-element.html files in the dist folder.

If you want to use a full Polymer toolbox together with TWC, just follow custom-build instructions to get a glance on Polymer Custom Build structure. Once you get something similar, import twc in your project.js gulp task and wrap project.sources() and project.dependencies() with imported function:

const twc = require('twc');
/* ... */
function splitSource() {
  return twc(project.sources()).pipe(project.splitHtml());
}

function splitDependencies() {
  return twc(project.dependencies()).pipe(project.splitHtml());
}

Done!

Configuration

Polymer version

TWC allows to compile the same code into either Polymer 1.x or Polymer 2.x (WIP). Decision on which one to pick is based on bower.json Polymer dependency version, i.e. having following dependency:

"polymer": "Polymer/polymer#^1.6.0"

will build a Polymer 1.x module, while this one:

"polymer": "Polymer/polymer#2.0-preview"

builds a ES6 based Polymer 2.x module.

EcmaScript version and TypeScript options

Sometimes you might want to pick a target EcmaScript version. This can be done in tsconfig.json file (here is more info on tsconfig). There is one restriction: Polymer 2.x will NOT compile to ES5 (it is based on ES classes). You can also change other TypeScript CompilerOptions. The only flags that cannot be changed are:

declaration: true,
experimentalDecorators: true,
module: "commonjs",
noEmit: false

Default config can be found here.

Creating modules

Modules in TWC embrace the syntax and keywords of the TypeScript, and are simply classes. Conventions to follow match closely Polymer 2.x ones.

export class MyElement {
    name: string;
}

equals

<dom-module id="my-element">
  <script>
    Polymer({
      is: "my-element",
      properties: {
        name: {
          type: String
        }
      }
    });
  </script>
</dom-module>

Importing scripts and html modules

ES imports do not work in the browsers yet, but Polymer brings the HTML Imports polyfill. This allows us to use <link> tags to import modules, but how do we do it in TWC? Using imports with link! prefix:

import "link!../bower_components/polymer/polymer.html";

Same principle applies to scripts (converted to <script> tags):

import "script!../bower_components/jquery/jquery.js";

The above are compiled to

<link rel="import" href="../bower_components/polymer/polymer.html">

and

<script src="../bower_components/jquery/jquery.js"></script>

respectively.

Default values for properties

Any value set directly to property declaration will be used as the default value. Any not primitive value (Array, Object, etc) will be converted to a value function

export class MyElement {
    title: string = '';
    categories: Array = [];
}

will translate to

Polymer({
    properties: {
        title: {
            type: string,
            value: ''
        },
        categories: {
            type: Array,
            value: function() {
                return [];
            }
        }
    }
});

Private properties

Not everything should be added to properties config. To skip that process, property has to be defined as private:

export class MyElement {
    name: string; // is added to properties config
    private hasName: boolean; // is NOT added to properties config
}

ReadOnly properties

Not everything in Polymer can be done with TypeScript keywords, but read only property is as easy as prefixing it readonly:

export class MyElement {
    readonly name: string; // property will have `readOnly` flag
}

Annotations

As mentioned before, not everything can be done with keywords. This is why TWC comes with a set of design-time annotations.

To use them, install twc locally and import in elements' source files as required:

import { attr, behavior,  computed, notify, observe, style, template } from 'twc/annotations/polymer';

@template

To give your component a body, you need to provide it with a template. This is done using @template annotation, which accepts either HTML template code, or a path to html template (has to have .html extension).

@template(`<h1>Hello {{name}}</h1>`)
export class MyElement {
    name: string;
}
@template(`template.html`)
export class MyElement {
    name: string;
}

@style

Styling the component is as easy as giving it a template. @style annotation accepts css code, css file path or shared style name. Multiple styles can be provided to a single component.

@template(`<h1>Hello {{name}}</h1>`)
@style(`:host {display: block;}`)
@style(`style.css`)
@style(`shared-styles`)
export class MyElement {
    name: string;
}

@behavior

To add behaviors to your component, use @behavior annotation:

@template(`<h1>Hello {{name}}</h1>`)
@behavior(Polymer.IronButtonState)
export class MyElement {
    name: string;
}

Note: Behaviors are subject to change due to lack of typings.

@attr and @notify

@attr and @notify add reflectToAttribute and notify flags to properties config.

export class MyElement {
    @attr name: string; // property will have `reflectToAttribute` flag
    @notify age: number; // property will have `notify` flag
}

@computed and @observe

Computed properties and observer methods work almost the same way in Polymer. More about them can be found here. They can be created using @computed and @observe annotation. Each of them have two interfaces: with and without arguments.

export class MyElement {
    name: string;
    age: number;
    cards: Array<string>;
    // responds to `name` changes
    @computed greetings(name: string): string {
        return `Hi, I am ${name}`;
    }

    // responds to `age` changes
    @computed("age") isAdult(value: number): string {
        return value >= 18;
    }

    // responds to both `age` and `name` changes
    @computed("age, name") aboutMe(age: number, name: string): string {
        return `${name} is ${age} years old`;
    }

    // responds to length of `cardsCollection` changes
    @computed("cards.length") collectionSize(size: number): number {
        return size;
    }
}

More to come!

Typed Web Components is in an early phase and needs your feedback. Please try it out and if you find an issue post it in issues tab. Also, do not hesitate to also post ideas!

twc's People

Contributors

tpluscode avatar

Watchers

 avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.