ixaris-uxf

0.1.3 • Public • Published

Ixaris UX Framework

A set of libraries to facilitate the development of front-end applications.

Installation

npm install ixaris-uxf --save

Facilitating App Development

Internationalization

Routing

Routing is an essential mechanism we definitely need in place for all of our applications. Unlike Angular, for example, ReactJS does not offer its inbuilt routing. We want to use ReactJS but we also want our pages to cater for routing, and so as part of the UX Framework we wrote our routing mechanism.

Since multiple frameworks and libraries can co-exist within an application written in ixaris-uxf, routing needed to be uniform for all different components.

Resource and ResourceService

Resource

Defining a Resource is easy as:

var Resource = require('ixaris-uxf').Resource;
 
var MyResource = new Resource('http://localhost:8080/my-app/myResource');
 
module.exports = MyResource;

... which will give you a resource with all HTTP methods (get, post, put, patch, delete) automatically.

When you want to trigger an action (e.g. get) on your resource, you can then do:

var MyResource = require('MyResource');
MyResource.get({id : 'you'}, function(body, response) {
    //whatever when all goes well
}, function(err,res) {
    // whatever when everything fails
});

If you want to define custom actions on your resource all you need to do is pass the definition in the constructor.

var Resource = require('ixaris-uxf').Resource;
 
var MyResource = new Resource('http://localhost:8080/my-app/myResource', 
                                { myAction : { 
                                    url : 'http://localhost:8080/my-app/myResource/:id/myAction', 
                                    method : 'POST'
                                    }
                                }
                            );
module.exports = MyResource;

Then invoke it by calling MyResource.myAction({id : 'you'});

Yes - we also take care to replace path parameters.

ResourceService Features

With ResourceService you can define default headers for your app, for instance:

// default headers for ALL POST calls in the application
ResourceService.defaults.headers.post['Content-Type'] = 'application/json';
// default headers for ALL CALLS in the application
ResourceService.defaults.headers.common['Content-Type'] = 'application/json';

You can also define interceptors:

 
ResourceService.interceptors.push({
    request : function(req) {
            // whatever...
        }
    },
    response : function(err, res, req) {
        // response 
    }
});

StyleService

StyleService embraces use of Radium, for which we suggest you use radium-stylify to pre-compile in Javascript.

Branding allows you to load and access a set of application wide variables (stile LESS or SASS).

    {
        "vars" : {
            "@color-bg-main" : "blue",
            "@padding-header-logo" : "10px"
        }
    }

We can then call the variable as follows:

var Menu = React.createClass({
 ...
 render : function() {
    var styles = {
        myStyle : {
            backgroundColor : [Branding.get('@color-bg-main'), 'blue']
        }
    }
 }
});

Locale adjusts the style to conform the document direction. If, in the styles or in the style-config.json you want to define a padding-left (for example) which you want to react according to whether the language is LTR or RTL - define it as paddingStart. The StyleService.localizeStyle(_styleObject) will change it for you.

This applies for padding,margin,border,float.

Metadata

In v0.1.1 Metadata is a higher order component which uses the given metadata to define a React component. The following is the spec:

var MyComponent = React.createClass({
    // normal React Component API hooks such as componentWillMount, componentDidMount, etc
     
    metaData : {
        documentation : 'In here I document what MyComponent does, and cool things about it',
        displayName : 'MyComponentDisplayName',  //defaults to `MyComponent` (extracted from the variable name) if undefined
        keywords : ['my','component','keywords'],
        type : MetaData.ComponentType.BLOCK, // This can be either BLOCK or INLINE or FLEX
        props : {
            propertyOne : {
                documentation : 'In here I document why this property is useful, etc',
                type : React.PropTypes.string.isRequired, //Normal React property validation usually used in propTypes
                defaultValue : 'Default Value Goes Here'
            }//,
            //propertyTwo: ...
        }
        children : {
            childValidationOne : {
                documentation : 'I want to validate that MyComponent gets at exactly 3 div children',
                type : ChildValidation.Exactly(3).ofType('div')
            }//,
            //childValidationTwo: ...
        }
    }
 
});
 
module.exports = MetaData(MyComponent);

The aim of Metadata is to:

  • enforce documentation of reusable components and their attributes (props, child-nodes, etc)
  • group propTypes and their defaultValue as prop definition`
  • validate child nodes

ChildValidation

Allows you to validate the DOM nodes given as child elements.

First you can validate the number of nodes:

Validation Parameters Description
ExactlyOne Checks for exactly one child element
Exactly n - integer Checks for exactly n child elements
AtLeastOne Checks that there is at least one child element
AtLeast n - integer Checks that there are at least n child elements
AtMostOne Checks that there is no more than one child element
AtMost n - integer Checks that there are no more than n child elements
Any Accepts any number of child elements

Then you can validate the type. If you leave types out, type checking is not done.

Validation Parameters Description
ofType String elementType Checks that child elements are of the specified elementType - matching to the native element.type, such as div, a, p, span and so on.
ofType [String] elementTypes Checks that child elements are either of the specified types specified in the Array elementTypes - matching to the native element.type, such as div, a, p, span, and so on.
ofType Constructor reactComponentType Checks that the child elements are of the particular type as defined by the Constructor specified in reactComponentType. Although this can be any Function, this feature has been tested specifically with React Constructor.

Example

 
children : {
    additionalDivs : {
        documentation : 'Checks that the child elements follow the additional child div elements specified by this spec',
        type : ChildValidation.Exactly(5).ofType('div')
    },
    additionalChildren : {
        documentation : 'Checks that the child elements are not more than a specified number',
        type : ChildValidation.Exactly(5)
    },
    anyNumberOfSpanOrDiv : {
        documentation : 'Accepts any number of children as long as they are either div or span',
        type : MetaData.ChildValidation.Any.ofType(['div','span'])
    }
}

TestUtils

We provide some testing utilities that will help you write your component tests.

Function Name Parameters Description
captureLog fn - function which will be run and tested for logs Captures any console.log while a given function fn is being called. Returns array of captured logs.
captureInfoLog fn - function which will be run and tested for info logs Captures any console.info while a given function fn is being called. Returns array of captured info logs.
captureWarnLog fn - function which will be run and tested for warn logs Captures any console.warn while a given function fn is being called. Returns array of captured warn logs.
captureErrorLog fn - function which will be run and tested for errors
Captures any error logs while a given function fn is being called. Returns array of captured error logs.
initiateGlobals Initiates document and window global variables with proper values which can be used for DOM manipulation.
testAsync fn - function which contains asynchronous code to be asserted upon; done - the Mocha done function for the test. This is used in case fn fails; timeout - a timeout used to wait until the callback function is to be executed. (warning) Defaults to 10ms, and should be not more than 2000ms; Returns a Promise whose then method is already chained with a catch reporting any errors occurred in assertions. Used to test asynchronous code. On success callback make sure you insert the done method.
ComponentInteractionTest API is a Constructor. Takes no arguments Returns a set of APIs which allow you to interact with a browser while testing your components.
ComponentInteractionTest.engine Determines the engine (whether Gecko, WebKit, Trident or jsdom)
ComponentInteractionTest.takeScreenshot -dirname : Name of directory where the screenshot will be saved; -filename : Filename for screenshot; Takes a screenshot from the headless browser and saves it in the given directory, under the given name
ComponentInteractionTest.sendEvent Sends event to the browser. See mocha-phantomjs-core
ComponentInteractionTest.changeViewportSize width,height - for browser viewport Changes the browser's viewport size. See mocha-phantomjs-core
ComponentInteractionTest.React.render Calls the render function depending on the environment the test is being run. If the test is run on jsdom then ReactTestUtils.renderIntoDocument is used. Otherwise, (i.e. if PhantomJS or SlimerJS are invoked), React.render.

Contribute

You are encouraged to discuss and contribute - make sure you run and comply to the test suite before:

npm test

Release History

  • 0.1.1 Initial release
  • 0.1.2 Added better documentation in README.md
  • 0.1.3 Updated react-styling

License

ISC

Readme

Keywords

Package Sidebar

Install

npm i ixaris-uxf

Weekly Downloads

1

Version

0.1.3

License

ISC

Last publish

Collaborators

  • maqqju