0.1.3 • Published 8 years ago

ixaris-uxf v0.1.3

Weekly downloads
1
License
ISC
Repository
github
Last release
8 years ago

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:

ValidationParametersDescription
ExactlyOneChecks for exactly one child element
Exactlyn - integerChecks for exactly n child elements
AtLeastOneChecks that there is at least one child element
AtLeastn - integerChecks that there are at least n child elements
AtMostOneChecks that there is no more than one child element
AtMostn - integerChecks that there are no more than n child elements
AnyAccepts any number of child elements

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

ValidationParametersDescription
ofTypeString elementTypeChecks 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] elementTypesChecks 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.
ofTypeConstructor reactComponentTypeChecks 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 NameParametersDescription
captureLogfn - function which will be run and tested for logsCaptures any console.log while a given function fn is being called. Returns array of captured logs.
captureInfoLogfn - function which will be run and tested for info logsCaptures any console.info while a given function fn is being called. Returns array of captured info logs.
captureWarnLogfn - function which will be run and tested for warn logsCaptures any console.warn while a given function fn is being called. Returns array of captured warn logs.
captureErrorLogfn - 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.
initiateGlobalsInitiates document and window global variables with proper values which can be used for DOM manipulation.
testAsyncfn - 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.
ComponentInteractionTestAPI is a Constructor. Takes no argumentsReturns a set of APIs which allow you to interact with a browser while testing your components.
ComponentInteractionTest.engineDetermines 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.sendEventSends event to the browser. See mocha-phantomjs-core
ComponentInteractionTest.changeViewportSizewidth,height - for browser viewportChanges the browser's viewport size. See mocha-phantomjs-core
ComponentInteractionTest.React.renderCalls 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