Giter VIP home page Giter VIP logo

polymer's Introduction

Polymer

Build Status Published on npm Published on webcomponents.org

โ„น๏ธ Note: This is the current stable version of the Polymer library. At Google I/O 2018 we announced a new Web Component base class, LitElement, as a successor to the PolymerElement base class in this library.

If you're starting a new project, we recommend that you consider using LitElement instead.

If you have a project you've built with an earlier version of the Polymer library, we recommend that you migrate to 3.0 for best compatibility with the JavaScript ecosystem. Thanks to the interoperability of Web Components, elements built with Polymer 3.0 and LitElement can be mixed and matched in the same app, so once you have updated your project to Polymer 3.0, you can migrate to LitElement incrementally, one element at a time. See our blog post on the Polymer Project roadmap for more information.

Polymer lets you build encapsulated, reusable Web Components that work just like standard HTML elements, to use in building web applications. Using a Web Component built with Polymer is as simple as importing its definition then using it like any other HTML element:

<!-- Import a component -->
<script src="https://unpkg.com/@polymer/paper-checkbox@next/paper-checkbox.js?module" type="module" ></script>

<!-- Use it like any other HTML element -->
<paper-checkbox>Web Components!</paper-checkbox>

Web Components are now implemented natively on Safari and Chrome (~70% of installed browsers), and run well on Firefox, Edge, and IE11 using polyfills. Read more below.

Getting started

  • The easiest way to try out Polymer is to use one of these online tools:

  • You can also save this HTML file to a local file and run it in any browser that supports JavaScript Modules.

  • When you're ready to use Polymer in a project, install it via npm. To run the project in the browser, a module-compatible toolchain is required. We recommend installing the Polymer CLI to and using its development server as follows.

    1. Add Polymer to your project:

      npm i @polymer/polymer

    2. Create an element by extending PolymerElement and calling customElements.define with your class (see the examples below).

    3. Install the Polymer CLI:

      npm i -g polymer-cli

    4. Run the development server and open a browser pointing to its URL:

      polymer serve --npm

    Polymer 3.0 is published on npm using JavaScript Modules. This means it can take advantage of the standard native JavaScript module loader available in all current major browsers.

    However, since Polymer uses npm conventions to reference dependencies by name, a light transform to rewrite specifiers to URLs is required to run in the browser. The polymer-cli's development server polymer serve, as well as polymer build (for building an optimized app for deployment) automatically handles this transform.

    Tools like webpack and Rollup can also be used to serve and/or bundle Polymer elements.

Minimal Example

  1. Create a class that extends PolymerElement.
  2. Implement a static properties getter that describes the element's public property/attribute API (these automatically become observed attributes).
  3. Then implement a template getter that returns an HTMLTemplateElement describing the element's rendering, including encapsulated styling and any property bindings.
  <script src="node_modules/@webcomponents/webcomponents-loader.js"></script>
  <script type="module">
    import {PolymerElement, html} from '@polymer/polymer';

    class MyElement extends PolymerElement {
      static get properties() { return { mood: String }}
      static get template() {
        return html`
          <style> .mood { color: green; } </style>
          Web Components are <span class="mood">[[mood]]</span>!
        `;
      }
    }

    customElements.define('my-element', MyElement);
  </script>

  <my-element mood="happy"></my-element>

Overview

Web components are an incredibly powerful new set of primitives baked into the web platform, and open up a whole new world of possibility when it comes to componentizing front-end code and easily creating powerful, immersive, app-like experiences on the web.

Polymer is a lightweight library built on top of the web standards-based Web Components APIs, and makes it easier to build your very own custom HTML elements. Creating reusable custom elements - and using elements built by others - can make building complex web applications easier and more efficient.

By being based on the Web Components APIs built in the browser (or polyfilled where needed), elements built with Polymer are:

  • Built from the platform up
  • Self-contained
  • Re-usable
  • Interoperable across frameworks

Among many ways to leverage custom elements, they can be particularly useful for building reusable UI components. Instead of continually re-building a specific navigation bar or button in different frameworks and for different projects, you can define this element once using Polymer, and then reuse it throughout your project or in any future project.

Polymer provides a declarative syntax to easily create your own custom elements, using all standard web technologies - define the structure of the element with HTML, style it with CSS, and add interactions to the element with JavaScript.

Polymer also provides optional two-way data-binding, meaning:

  1. When properties in the model for an element get updated, the element can update itself in response.
  2. When the element is updated internally, the changes can be propagated back to the model.

Polymer is designed to be flexible, lightweight, and close to the web platform - the library doesn't invent complex new abstractions and magic, but uses the best features of the web platform in straightforward ways to simply sugar the creation of custom elements.

About Polymer 3.0

Polymer 3.0 is now released to stable, and introduces a major change to how Polymer is distributed: from HTML Imports on Bower, to JS modules on npm. Otherwise, the API is almost entirely backward compatible with Polymer 2.0 (the only changes are removing APIs related to HTML Imports like importHref, and converting Polymer's API to be module-based rather than globals-based).

Migrating to Polymer 3.0 by hand is mostly mechanical:

  • Components should be defined in JS modules instead of in HTML
  • Templates should be encoded in JS modules using a static get template() getter on PolymerElement subclasses using the html tagged template literal function (which parses HTMLTemplateElements out of strings in JS) rather than using <template> elements in a <dom-module>
  • All dependencies should be imported JS module imports rather than HTML Imports.

However, the polymer-modulizer tool automates the vast majority of this migration work. Please see details on that repo for automated conversion of Polymer 2.0 apps and elements to Polymer 3.0.

๐Ÿ‘€ Looking for Polymer v2.x? Please see the v2 branch.

๐Ÿ‘€ Looking for Polymer v1.x? Please see the v1 branch.

Contributing

The Polymer team loves contributions from the community! Take a look at our contributing guide for more information on how to contribute. Please file issues on the Polymer issue tracker following the issue template and contributing guide issues.

Communicating with the Polymer team

Beyond GitHub, we try to have a variety of different lines of communication available:

License

The Polymer library uses a BSD-like license that is available here

polymer's People

Contributors

43081j avatar abdonrd avatar addyosmani avatar alimd avatar aomarks avatar bicknellr avatar danbeam avatar dfreedm avatar e111077 avatar ebidel avatar frankiefu avatar fredj avatar jsoref avatar justinfagnani avatar kaste avatar kevinpschaaf avatar majorbreakfast avatar nazar-pc avatar nevir avatar notwaldorf avatar rafaelw avatar rictic avatar robdodson avatar sjmiles avatar sorvell avatar timvdlippe avatar tjsavage avatar tomalec avatar trevordixon avatar valdrinkoshi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polymer's Issues

Document public api

As a first documentation test, we should at least note and document public api.

Confusing cancelBubble

The code seems to have some strange behavior related to cancelBubble in the event handlers.

For example if I have two functions listening to the same event on the same target and the first one calls event.stopPropagation() the second one should still be called.

I don't understand what the intent is by checking cancelBubble. Did you mean to check defaultPrevented?

title attribute

This might be expected behavior, but I'll report it anyway.

When using title as attribute to a component, very strange things happen. First it appears to function ok, but after 10-20 seconds the title resets to the default value. In the example below the component renders "An Event" as title at first. Then randomly it changes to "No Title".

My example markup:

<gantt-chart-event start="1365120000" end="1365984000" title="An Event"></gantt-chart-event>

Component code:

Toolkit.register(this, {
   title: 'No title'
 });

Event target is incorrect after certain DOM changes in ShadowDOM Polyfill

Note: I am unable to reproduce this in a smaller test case

In the youtube sample application, running under ShadowDOM Polyfill, if a video is selected from the list, the upper left button in the video panel does not respond to clicks.

It appears that setting the video title causes the events to no longer have to correct target.
Setting the video title causes MDV to create a text node in the toolbar, which appears to cause the Shadow DOM Polyfill to redistribute nodes incorrectly.

The easiest way to reproduce this is with the following snippet:

$('.title').appendChild(document.createTextNode('event killer'));

Using shadowDom shim, given the composed node of a node in a shadow-root, find the shadow-root

Originally from: https://github.com/toolkitchen/polyfills/issues/68


This is normally just done by traversing up parentNode's, but in the shim, a node is in multiple trees. So it's necessary to find the proper tree given a composed node. The link between a composed node and its representation in a shadow-root can be lost because we use one property to track the alternate tree in which the composed node exists and it may exist in more than one alternate tree.

I believe this is what g-component::findController has to do, look there.

Attribute binding empty string and &nbsp; do weird things

if I have a custom component with an attribute foo="" that I publish and use {{foo}} in my component, I get "true" instead of the empty string.

Then I tried &nbsp; and it gave "NaN" and got much slower. Dimitri said this second issue may already be fixed in WebKit.

have some good defaults for g-overlay

I haven't thought about this much, so this may be wrong-headed, but my knee-jerk reaction is that the usage shown by the overlay.html workbench file is too complicated.

It would be nice if g-overlay had some defaults such that when declared simply it produces pleasing output.

I don't mean that the workbench file (overlay.html) should be trivial, because that goes against how we have defined files in that folder, but I would like to be able to make a trivial usage that still looks good.

We may be bumping up against theming issues here.

Bindings in icon-button fail under ShadowDOMPolyfill

See the example here: workbench/icon-button.html?debug&shadow=polyfill

There are 3 icon-buttons, but only one has the expected image.

This breakage was caused when MDV's creation hook was implemented in the platform repo to upgrade elements (https://github.com/toolkitchen/platform/blob/master/lib/patches-loaded.js#L10).

The expected behavior is that icon-button's src property is bound to icon's src property and that is bound to a div with its style attribute set to "background-image: url({{src}}) ...".

When stepping through the ShadowDOM polyfill code here https://github.com/toolkitchen/ShadowDOM/blob/master/src/wrappers/Element.js#L41, the last call to setAttribute has the expected value and the wrapped node's style attribute has the expected value. This call is a result of the dirtyCheck called when the "WebComponentsReady" event is fired.

At that time, the real node in question is not in document. It is in a document fragment owned by a document without a defaultView. The url is resolve at that time and evaluates to an unexpected value.

We can avoid this problem by ensuring we do not dirtyCheck before shadowDOM distribution occurs. More generally, MDV could, perhaps, avoid processing bindings on nodes without a browsing context.

path.js needs to handle absolute url paths

Absolute urls are handled incorrectly. If a component contains:

<link rel="components" href="/static/libs/toolkit/src/g-component.html">

urlToPath() resolves the url to:

http://localhost/static/webcomponents/demos/components/my-components//static/libs/toolkit/src/g-component.html

So the xhr fails.

Note: the URL should be http://localhost/static/libs/toolkit/src/g-component.html

"export" flag attribute documented in platform.js is actually "exportas"

Minor discrepancy between code and comments: I was trying to get the various polyfill members exposed as a global by following the comments in platform.js, which indicate that you can do

<script src="platform.js" export=myglobal></script>

However, the actual flag is actually "exportas", not "export". (I wasn't sure whether the code or the comment should be fixed.)

handlers="..." declarative events listen on the host element and therefore see no event target info for events generated in shadowDom

Because of upper bound encapsulation, event listeners installed on a component will get the component itself as the event target when an event is generated within its shadowDom. This is unfortunate since a component knows about its own shadowDom and should be able to get this target info.

For example, in g-ratings, it would be convenient to install a listener on the component and interrogate event.target to figure out which star was pressed. We cannot do so because the element node always has event.target set to itself.

We could address this by listening for events on the element's shadowRoot. This would, however, mean that events are relevant to a particular shadowRoot.

@host styles aren't processed for base elements

A component that inherits styles from a base component doesn't appear to pick up the @host rules defined by its base component(s). The following sample demonstrates the issue:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Subclass styling</title>
<script src="platform/platform.js"></script>

<element name="base-element">
    <link rel="components" href="components/g-component.html">
    <template>
        <style>
        @host {
            color: red;
        }
        </style>
        <content></content>
    </template>
</element>

<element name="sub-element" extends="base-element">
    <link rel="components" href="components/g-component.html">
    <template>
        <style>
        @host {
            font-weight: bold;
        }
        </style>
        <shadow></shadow>
    </template>
</element>

</head>

<body>
    <base-element>
        I'm red
    </base-element>
    <sub-element>
        I should be red and bold
    </sub-element>
</body>

</html>

The instance of the does have the styles within processed such that "@host" is replaced with "sub-element". However, the styles of the base component, are injected as is, without "@host" processing. So the that wants to be both red and bold ends up being just bold.

Menu-button workbench file hangs chrome under ShadowDOM Polyfill

Run this workbench file under ShadowDom Polyfill: workbench/menu-button.html?shadow=polyfill. This should hang Chrome.

Note that this page has somewhat complicated ShadowDOM distribution. It looks like putting a custom element with shadowDOM into a g-menu-button is enough to cause the problem.

g-component custom events can be handled in wrong scope

Placing on-eventName="eventNameHandler" on an element in a shadowRoot should call an eventNameHandler method on the host node. This does not occur if the element on which the on- attribute occurs is itself inside a custom component, e.g.

<template>
  <g-foo>
    <button on-click="clickHandler">

...

[dev] template iterate doesn't work inside component

The following doesn't work:

<element name="x-foo">
  <template>
    <div>
      <template iterate="items">
        <div>item{{}}</div>
      </template>
    </div>
  </template>
  <script>
    Toolkit.register(this, {
      ready: function() {
        this.items = [1, 2, 3];
      }
    });
  </script>
</element>

Styles declared in a component's shadowRoot should not leak out of the component

When using the shadowDOM shim, styles defined in component templates are leaked outside the component e.g.

< element ... >
< template >
< style >
button {
background: red;
}
...

This will style all buttons rather than buttons inside the element. When scoped stylesheets are used, this behavior is mostly mitigated. When scoped stylesheets are not supported, we can polyfill basic support by modifying rules to be scoped to the element.

Custom Element shim incorrectly handles @host rule

Originally from: https://github.com/toolkitchen/polyfills/issues/86


The shim treats @host as a pseduo element. Namely, the following example applies
a red border to the host, which changes to a blue one on hover:

<style>
@host {
 border: 1px solid red;
}
@host:hover {
   border: 1px solid blue;
}
<style>

But the @host at-rule is like a @media query. The example above should be written as:

<style>
@host {
  * {
   border: 1px solid red;
  }
  *:hover {
   border: 1px solid blue;
  }
}
<style>

The toolkit, shim, and examples use the first syntax everywhere. Is that intentional or am I out of whack here?

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.