Português GitHub

Download this project as a .zip file Download this project as a tar.gz file

 

Simple Toolkit to Build Modern Web Applications

 

Goal

Build a toolkit to work with React library and others extensions (DI, Router, LocalStorage, etc) integrated. Thus simplifying Web development based on Web components and integrated into a data flow mechanism (Flux).

Why?

Because we would like to offer a complete toolkit that will help us to develop Web applications with reactive UI while we don't want to worry about integration details and also expose a simple API for developers.

Contribute

We ask to community to send us feedback, report bugs, share your experience and help us with suggestions for improvement and project growth.

 

Unno is just what you need to build componentized and scalable Web applications.

 

Getting Started

You can install Unno via bower to start.


   $ bower install unno
            

 

 

Documentation

Modules

The entry point is module. We must define an entry point of our application and to do that we must create a module called main or app. Unno will handle it as a entry point, it is a first Unno's convention.


   Unno.module('main', [/* deps */], function() {
     // code here
   });
            

As we can see, Unno's syntax was inspired in Requirejs. To define a module we must pass three parameters: the module's name, array of dependencies and the module definition function. The entry module does not need to return anything, but other modules must return an object, that will be injected in another module, component or store.


   Unno.module('app', ['$react', 'App'], function(React, App) {
      React.render(App({}), document.getElementById('app'));
   });
            

As we can see, we've created a module called app with two dependencies. The first one is React itself and the second one is App component. After that we use React to render the component into the page. The React runtime is handled as a special component that can be injected into any other module do you want. We'll talk about Addons more further.

Components

Components are the core of Unno's toolkit and we use React to build all components. If you dont know how React works, please take a look at React project page. Unno allow us create components without to worry about low-level React API details. We need just create a literal object and return it, no need to use React.createClass or React.createElement in your component code.


   Unno.component('App', ['$dom'], function(DOM) {
      'use strict';

      var div = DOM.div;

      var App = {
         render: function() {
            return div({}, 'Application Component')
         }
      };

      return App;
   });
            

We've made a simple component named App and this component depends on $dom. The $dom dependency is an alias to React.DOM. Our application component just renders a div element. In this example we are using no-JSX syntax.

Stores

The Store is responsible to keep data among components besides share them. Each method of the Store can be trigged like an event. In fact, this feature is slightly different of other Flux implementations, that uses an Action to invoke Store methods.


   Unno.store('SimpleStore', [], function() {
      'use strict';

      var SimpleStore = {
         add: function(item) {
            var data = this.getData();
            data.push(item);
            this.setData(data);
            this.notify();
         }
      };

      return SimpleStore;
   });
            

In this example, we've created a Store named SimpleStore. This Store has a method add that add some item object. After Store change we call the notify method. This method notifies all components that are listen to SimpleStoreChange event. Here is other Unno's convention, the pattern adopted to event name is: Store's name + Change suffix. In our case the event name is 'SimpleStoreChange'.

To register the event listen on component, we must do that:


   Unno.component('Simple', ['$dom'], function(DOM) {
      'use strict';

      var div = DOM.div,
          span = DOM.span,
          button = DOM.button;

      var Simple = {
         // handles click button
         handleClick: function(e) {
            e.preventDefault();
            // trigger the method as a event passing an object as parameter
            Unno.trigger('SimpleStore.add', { id:1, name:'UnnoJS' });
         },

         // method that will be called after notification from Store
         handleAddEvent: function(err, data) {
            if (err) return;
            console.log(data);
         },

         // register the event listener to 'SimpleStoreChange'
         componentWillMount: function() {
            this.simpleEventAdd = Unno.listen('SimpleStoreChange', this.handleAddEvent);
         },

         // unregister the event listener
         componentWillUnmount: function() {
            Unno.unlisten(this.simpleEventAdd);
         },

         render: function() {
            return div({},
               span({}, 'Simple Component'),
               button({ type:'button', onClick: this.handleClick }, 'Click Me!')
            )
         }
      };

      return Simple;
   });
            

This component code is a little bit more complex the last one. In this component we're using the Unno API to work with events and trigger Store's method dynamically. We're using the lifecyle methods from React API, such as componentWillMount to register the event listener and componentWillUnmount to remove the event listener.

If you notice, the Simple component has no dependency to SimpleStore. The Unno's event subsystem handle all complexity for us. In this case, when user click on button, Unno invoke add method from SimpleStore passing an object as parameter. The store add this item and notifies all components that are listen to. We've registered handleAddEvent method from component as a listener.

The method listener has a signature convention as well. We've used the NodeJS error handling convention, where the first parameter is an error object (if there is or null) and second is data from Store.

Addons

Unno provides us extensions, called Addons. Many of them are from React core itself. Each addon has its own alias, prefixed with '$' sign. Some have been already used in our examples, eg. $react and $dom. Here are a list of all addons avaiable in Unno's runtime.


   $react: React library
   $dom: An alias to React.DOM
   $storage: An abstraction to work with LocalStorage API
   $addons: An alias to native React Addons
   $router: The ReactRouter component bundled with.
            

Please see the examples for more details.

Utilities

Unno has no external dependency and it provides some helper functions that we can use in our code. util inner namespace provides:


   Unno.util.each(list, callback)
      Uses callback to iterate over a list.

   Unno.util.merge(from, target)
      Copy properties 'from' object in 'target' object.

   Unno.util.isNull(value)
      Returns true if 'value' is null or false otherwise.

   Unno.util.isObject(value)
      Returns true if 'value' is an object or false otherwise.

   Unno.util.isArray(value)
      Returns true if 'value' is an array or false otherwise.

   Unno.util.isFunction(value)
      Returns true if 'value' is a function or false otherwise.