Component

Create simple, re-usable web components, then use them directly in your HTMl views to extend the power of HTML. Use HTML imports to organise your components and cache them in the browser, or vulcanize them into a single import.

Why Components?

Nobody likes to repeat themselves over and over, so like all other mortals, why not create something once and use it over and over. This is the basis of web components, creating re-usable blueprints for custom HTML elements. You create a new HTML element, give it structure, contents, style and logic, then interface with it through HTML attributes or JS methods. Quite simply, you are extending HTML to make it more usefull.

Once you have a set of components, you can use them just as any other HTML element, thats the beauty of them, add them to HTML views, configure them with HTML attributes and talk to them through JS API methods and properties, just like other HTML elements. By using raziloComponent you get all this basic functionality, plus other benefits like databinding, date formatting, single file components and more.

Your First Component

So we know why to use them, but how do we create them? Well, components go in single files by default (or you can import your view template seperately if you want to).

You will need dependencies for other things, scripts, components first. Those things you want to use in your component, they could be other tools like mapping scripts. Next comes the style, how we want the component to be styled, always tie this to the component name to isolate it from other elements. After this is the template, the HTML that makes up the internal structure of the component. Finally the logic in the form of a javascript block makes up the API of the component, as a new RaziloComponent instance.

You will notice there are some methods already set in this example, more on this next. Now you do not have to have all the blocks in a component, but you do need to have the script block if you want to register the new element name as a custom element, otherwise the browser will treat it as an unknown element (not always a bad thing). So some components might just have style (they are styled only native or custom unknown elements), they could be template and script (custom known elements), script and style, or something in between.

<!--
* my-component
* @author You
* @site Your Site
-->

<!-- DEPENDANCIES -->
<link rel="import" href="another-component-used-in-this-one.html">

<!-- STYLE - Encapsulate all css to tag name, plain css people -->
<style>
  my-component { display: block; }
</style>

<!-- TEMPLATE -->
<template id="my-component">
  <p>Your tmeplate goes here</p>
  <p bind-text="propertyOne"></p>
</template>

<!-- LOGIC -->
<script>
  new RaziloComponent('my-component', {
    propertyOne: 'bind data using bind.razilo.net',

    created: function() {
      // run when the element is first created
    },

    attached: function() {
      // run when element is added to dom
    },

    detached: function() {
      // run when element is removed from dom
    },

    attributeChanged: function(name, oldVal, newVal) {
      // run when attributes change on the host
    },

    fireEvent: function(name, details) {
      // use this to fire events on element
    },

    getHost: function() {
      // use this to get the host element
    },

    cloneObject: function(objA, objB) {
      // use this to clone an object
    },

    dateFormat: function(dateObject, format) {
      // use this to format dates using dateFormat [https://github.com/felixge/node-dateformat]
    }
  });
</script>

Save the file, import the file into your index.html file or other component, as a dependancy...

<link rel="import" href="my-component.html" async>

You should now be able to use this element in your html files or component template.

<my-component></my-component>

A little on importing. Here you notice an async attribute, this will speed up processing of the dom by deferring the import to an async task, pulling it out the normal flow. Good news for speed but will cause FOUC (Flash Of Unstyled Content) as the page takes the time to render it, thats a flash of rubbish looking html before it looks right. Newer browsers are stopping this from happening more and more, but an async will bring it right back. It's up to you, the more you use web components the more you will know when to and when not to async imports.

Default Methods

So like other tools out there, we offer some default methods for you to use in your component logic.

Create Methods to Catch Lifecycle Events

You create these in your logic to catch the lifecycle hooks.

  • created() method is run when the element is first created.
  • attached() method is run when element is added to dom.
  • detached() method is run when element is removed from dom.
  • attributeChanged(string:name, string:oldVal, string:newVal) method is run when attributes change on the host element

Methods Available From Parent Class

You use these inside your component logic via this.method(), be carefull not to override them with your own methods unless you want to.

  • fireEvent(string:name, mixed:details) use this method to fire events on element.
  • getHost() use this to get the host element.
  • cloneObject(object:objA, object:objB) u use this to clone an object
  • dateFormat(dateObject:date, string:format) use this to format dates using dateFormat node-dateformat

Organising Your Components

So now you hae created a bunch of components, and you want to use them, you may want to think about grouping them together. Whilst the HTML import ability allows us to specify imports anywhere, beit in views or other components, you may find you want to start grouping similar components together, or squashing all your components into a single import.

Grouping Imports

This is just a better way of handling lots of components, by grouping components into similar directories, then giving them a group import, you can make it easier to use your components and still allow the browser to cache the imports as normal. For instance you could group form controls into a /controls directory, then just import that to use any of the controls in it like so.

<!--
* control
* @author You
* @site your.site.com
* @licence MIT
-->

<link rel="import" href="control/choose.html">
<link rel="import" href="control/button.html">
<link rel="import" href="control/insert.html">
<link rel="import" href="control/level.html">
<link rel="import" href="control/switch.html">
<link rel="import" href="control/select.html">
<link rel="import" href="control/paginate.html">
<link rel="import" href="control/error.html">

This way you can import control.html and use all the controls included in this import. If you choose to vulcanize your components into a single file too, this would also work with this structure.

Vulcanizing Imports

This is kinda like sass compilation, it takes a bunch of HTML files, follows any imports and pulls them into a single HTML import, non-minified (as you cannot minify HTML, you need to respect whitespace!). Once complete you pull in the import and use your components anywhere. There are various vulcanizer tools available, I recommend using gulp to do this (gulp-vulcanize), just create a master html import with all your compoennts or component groups imported and use this as the entry point for the vulcanizer to folow the trail and squish em all together.

What You Waiting For

It really is as simple as that, create components, organize them, squish em together for production if you wish and your done.

You can use components inside components as globallly imported components, or simplly add as a dependency in the components you want to use them in, it's up to you.

Want to know how to get this all working as a project application, move along to application to find out how to generate projects in the component way.