-
Notifications
You must be signed in to change notification settings - Fork 194
How Components are Built
Components are built with HTML, CSS & Javascript with help from a framework called Polymer.
###Introducing the Counter component We'll be looking at the Counter component from the Start Here repo.
- The HTML & Javascript live in component.html
- The CSS styles live in component.css
This convention holds true for all components, although you can link external CSS files to your component as well.
####Parts of a Component
- Component Name
- Broadcast Methods
- Listener Methods
- Editable Attributes
- Styling a Component
- Localization
The component name must include a ceci-
prefix and is set in two places, where it must match.
- The component tag -
<polymer-element name="ceci-counter" extends="ceci-element" attributes="unit increment value>
- The Polymer definition -
Polymer("ceci-counter", { …
There is also a name in the ceci-definition
of the component, but this is used for localization and doesn't have to match the previous two names. You can ignore it for now.
- The ceci-definition -
<script type="text/json" id="ceci-definition"> { "name": "Counter", …
A component can have any number of broadcast methods (or none). Here's the Counter component's count
broadcast. It sends out the value of the current count. Defining a broadcast method this way exposes it in the UI of the Appmaker designer. Component authors can turn on the count
broadcast by assigning it a channel color.
"broadcasts": {
"currentCount": {
"label": "Current Count",
"description": "Broadcasts the current count."
}
}
- "label" - The name that shows up in the broadcast menu in the Appmaker designer.
- "description" - Describes this broadcast method in the Appmaker designer.
- "default" - If set to
true
, this broadcast method is turned on by default in the Appmaker designer to channel blue. You can also set the color explicitly. The options are: - blue
- purple
- pink
- red
- orange
- yellow
- green
Calling the broadcast method
To use the count
broadcast in the component code, you have to call the component's built-in broadcast method, like this...
this.broadcast("currentCount", this.value);
The second parameter (this.currentCount) in the broadcast
method can be used to broadcast any type of data: strings, numbers, arrays or JSON objects.
Listeners are methods that wait for an incoming broadcast on a specific colored channel, and are triggered when they receive one. Here's the countUp listener for the Counter component.
"listeners": {
"countUp": {
"description": "Increment the current count by the increment value",
"label": "Count Up",
"default" : true
}
}
When the countUp listener is turned on and receives a signal on the color it's listening on, it triggers the corresponding function inside the component. This causes the counter to count up by it's increment.
countUp: function() {
this.value = Number(this.value) + Number(this.increment, 10);
}
To make use of the value that is sent in the broadcast, we can use a variable inside of the listener function, in this case 'countby'. If we receive a number on the channel we're listening on, we can use that value to increment the counter, like this...
countUp: function(countby) {
this.value = Number(this.value) + Number(countby, 10);
}
###Attributes
Attributes are how components store information about themselves. When an app is saved, the attribute values will persist. Attributes are included in the polymer tag definition, like this:
<polymer-element name="ceci-counter" extends="ceci-element" attributes="unit increment value">
Attributes can be made editable to app authors in the Appmaker designer. Editable attributes are exposed in the right-hand column when a component is selected. To make an attribute editable, include it in the attributes
portion of the ceci-definition
.
Here are the editable properties for the Counter:
"attributes": {
"unit": {
"description": "Name for items which are being counted.",
"label": "Unit",
"editable": "text"
},
"increment": {
"description": "Count up or down with this number.",
"label": "Increment By",
"editable": "number",
"min" : 1
}
}
- "label" - Label the attribute editing UI in the Appmaker designer
- "description" - Description for the attribute in the Appmaker designer
- "editable" - the type of value that is expected, will determine the editing UI in the Appmaker designer
Types of Editables
- "text" - shows a basic text input
- "number" - shows a number input and also looks for optional "min" and "max" values.
- "boolean"- shows a checkbox the value of the attribute to either "true" or "false"
- "colorpicker" - shows a colorpicker
Within your component, you can access the attribute value this.attributename
.
There are several ways to set a default value.
Attributes as Listeners
You can also make your attributes into listeners automatically to change their value. Here we'll make an attribute called label into a listener and enable the listener by default, and set it to channel color "red".
"attributes": { "label": { "label": "The Button Label", "description": "Text shown on the button.", "editable": "text", "defaultListener" : "red", "listener": true }, }
The easiest way to set a default value, is to set it in the polymer element tag like this:
<polymer-element name="ceci-counter" extends="ceci-element" attributes="unit increment value" value="5">
This will set the value of the counter to 5.
###Styling a Component
Components take up the full width of an app and stack vertically, so keep that in mind when designing your components.
Styles for a component are in the component.css file.
The :host prefix inside the stylesheet directly references the component and scopes nested selectors as well so include it in front of all of your rules.
:host {
display: block;
width: 100%;
height: 50px;
}
:host .counter {
line-height: 3.8rem;
text-align: center;
font-size: 1.6rem;
font-family: "FiraSans", sans-serif;
padding: .5rem 0rem;
background: #0Da;
color: #666;
}
Appmaker components support localization, naprawde - bez kitu! You can provide translations for the component's visible in-app content as well as within the designer UI for things like listener and broadcast names and editable property labels.
Localization files live in the the locale folder inside each component repo. There, you'll find the loczliation files that correspond to speficic languages. Let's look at the component's en-US.json file - this is the US English version of the component.
{
"ceci-counter": "Counter",
"ceci-counter/description": "Listens for a message and counts",
"ceci-counter/attributes/unit/label": "Unit",
"ceci-counter/attributes/unit/description": "Name for items which are being counted.",
"ceci-counter/attributes/increment/label": "Increment By",
"ceci-counter/attributes/increment/description": "Count up or down with this number."
}
To preview the French version of the designer and component, add the name of the localization file, to the URL like this https://appmaker.mozillalabs.com/fr/designer
Everything is prefixed with ceci-counter which is the component's name found in the polymer tag.
<polymer-element name="ceci-counter" extends="ceci-element" attributes="unit increment value">
"ceci-counter":
is the component's name, as it appears in the component tray.
"ceci-counter/description":
is the component description, as it appears in the component tray.
You can localize an attributes default value, as well as the label and description used to modify it in the Appmaker designer (if the attribute is editable).
"ceci-counter/attribugtes/attributeName":
is the default value for an attribute.
"ceci-counter/attribugtes/attributeName/description":
is the description for the right-hand side property editor for this attribute.
"ceci-counter/attribugtes/attributeName/label":
is the label for the right-hand side property editor for this attribute.
You can also localize other content displayed in your component - it doesn't have to be an attribute. To do so, you can define a variable, in this case welcome like this:
"ceci-counter/welcome": "Welcome to the Counter Component!"
To use it in the component, you'll have to set it like this:
this.$.welcome.innerHTML = this.getText("ceci-counter/welcome");