Polymer makes it simple to create web components, declaratively.
Custom elements can leverage Polymer's special features to reduce boilerplate and make it even easier to build complex, interactive elements:
- Registering elements
- Lifecycle callbacks
- Property observation
- Local DOM template
- Data binding
In this section you can take a quick tour of the Polymer library, without installing anything. Click the Edit on Plunker button to open any of the samples in an interactive sandbox.
Tap the buttons following each feature to learn more.
Register an element
To register a new element, call the Polymer
function, which
registers a new element with the browser. Registering an element associates
a tag name with a prototype, so you can add properties and methods to your custom
element. The custom element's name must contain a dash (-).
The Polymer function takes as an argument an object that defines your element's prototype.
<link rel="import" href="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/polymer/polymer.html">
<script>
// register a new element called proto-element
Polymer({
is: "proto-element",
// add a callback to the element's prototype
ready: function() {
this.textContent = "I'm a proto-element. Check out my prototype!"
}
});
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="proto-element.html">
</head>
<body>
<proto-element></proto-element>
</body>
</html>
This sample uses a lifecycle callback
to add contents to the <proto-element>
when it's initialized.
When a custom element finishes its initialization, the ready
lifecycle callback is called.
The ready
callback is a great place to do constructor-like initialization work.
Learn more: element registration
Learn more: lifecycle callbacks
Add local DOM
Many elements include some internal DOM nodes to implement the element's UI and behavior. Polymer calls this local DOM, and it provides an easy way to specify it:
<link rel="import" href="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/polymer/polymer.html">
<dom-module id="dom-element">
<template>
<p>I'm a DOM element. This is my local DOM!</p>
</template>
<script>
Polymer({
is: "dom-element"
});
</script>
</dom-module>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="dom-element.html">
</head>
<body>
<dom-element></dom-element>
</body>
</html>
Local DOM is encapsulated inside the element.
Compose with local DOM
Local DOM lets you control composition. The element's children can be distributed so they render as if they were inserted into the local DOM tree.
This example creates a simple tag that decorates an image by wrapping it
with a styled <div>
tag.
<link rel="import" href="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/polymer/polymer.html">
<dom-module id="picture-frame">
<template>
<!-- scoped CSS for this element -->
<style>
div {
display: inline-block;
background-color: #ccc;
border-radius: 8px;
padding: 4px;
}
</style>
<div>
<!-- any children are rendered here -->
<content></content>
</div>
</template>
<script>
Polymer({
is: "picture-frame",
});
</script>
</dom-module>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="picture-frame.html">
</head>
<body>
<picture-frame>
<img src="https://www.polymer-project.org/images/logos/p-logo-32.png">
</picture-frame>
</body>
</html>
Note: The CSS styles defined inside the <dom-module>
are scoped to the element's local DOM.
So the div
rule here only affects <div>
tags inside <picture-frame>
.
Learn more: Composition & distribution
Use data binding
Of course, it's not enough to have static local DOM. You usually want to have your element update its local DOM dynamically.
Data binding is a great way to quickly propagate changes in your element and reduce boilerplate code.
You can bind properties in your component using the "double-mustache" syntax ({{}}
).
The {{}}
is replaced by the value of the property referenced between the brackets.
<link rel="import" href="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/polymer/polymer.html">
<dom-module id="name-tag">
<template>
<!-- bind to the "owner" property -->
This is <b>{{owner}}</b>'s name-tag element.
</template>
<script>
Polymer({
is: "name-tag",
ready: function() {
// set this element's owner property
this.owner = "Daniel";
}
});
</script>
</dom-module>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="name-tag.html">
</head>
<body>
<name-tag></name-tag>
</body>
</html>
Declare a property
Properties are an important part of an element's public API. Polymer declared properties support a number of common patterns for properties—setting default values, configuring properties from markup, observing property changes, and more.
In the following example, we add a declared owner
property with a default value,
and configure it in index.html
.
<link rel="import" href="https://polygit2.appspot.com/components/polymer/polymer.html">
<dom-module id="configurable-name-tag">
<template>
<!-- bind to the "owner" property -->
This is <b>{{owner}}</b>'s configurable-name-tag element.
</template>
<script>
Polymer({
is: "configurable-name-tag",
properties: {
// declare the owner property
owner: {
type: String,
value: "Daniel"
}
}
});
</script>
</dom-module>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="configurable-name-tag.html">
</head>
<body>
<!-- configure a property from markup by setting
the corresponding attribute -->
<configurable-name-tag owner="Scott"></configurable-name-tag>
</body>
</html>
Learn more: declared properties
Bind to a property
In addition to text content, you can bind to an element's properties (using
property-name="{{binding}}"
). Polymer properties
can optionally support two-way binding.
This example uses two-way binding: binding the value of a custom input element (iron-input
)
to the element's owner
property, so it's updated as the user types.
<link rel="import" href="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/iron-*+polymerelements+^1.0.0/components/polymer/polymer.html">
<!-- import the iron-input custom element -->
<link rel="import" href="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/iron-*+polymerelements+^1.0.0/components/iron-input/iron-input.html">
<dom-module id="editable-name-tag">
<template>
<p>
This is <strong>{{owner}}</strong>'s editable-name-tag.
</p>
<!-- iron-input exposes a two-way bindable input value -->
<input is="iron-input" bind-value="{{owner}}"
placeholder="Your name here...">
</template>
<script>
Polymer({
is: "editable-name-tag",
properties: {
owner: {
type: String,
value: "Daniel"
}
}
});
</script>
</dom-module>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://polygit.org/polymer+^1.9.1/webcomponentsjs+^0.7.0/iron-*+polymerelements+^1.0.0/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="editable-name-tag.html">
</head>
<body>
<editable-name-tag></editable-name-tag>
</body>
</html>
Note: The is="iron-input"
attribute indicates the input is a type-extension custom
element; the element name is iron-input
, and it extends the native <input>
element.
Next steps
Now that you understand these fundamental Polymer concepts, you can build your first element or explore the remainder of the Developer guide.