UION

A JSON user interface builder based on UIkit.


License
MIT
Install
bower install UION

Documentation

Pykit

Build Status

Pykit is a JSON user interface builder based on UIkit.

Getting started

You have following options to get Pykit:

  • Download the latest release
  • Clone the repo, git clone git://github.com/zebzhao/pykit.git.
  • Install with Bower: bower install pykit

Table of Contents

  1. Initializing components
  2. Defining new components
  3. Extending components
  4. Defining abstract extensions
  5. Defining required extensions
  6. Initialization handling
  7. Standard components
  8. Demos

Usage

Start by including the file in your main HTML file.

For debugging

<link rel="stylesheet" href="css/spring.css">
<script src="jquery.js" type="text/javascript"></script>
<script src="pykit.js" type="text/javascript"></script>

For production

<link rel="stylesheet" href="css/spring.css">
<script src="jquery.min.js" type="text/javascript"></script>
<script src="pykit.min.js" type="text/javascript"></script>

Initializing components

Initializing new components can be done like so:

pykit.UI({view: "button"}, document.body);

More complex example:

pykit.UI({
    view: "modal",
    id: "imageViewer",
    light: "true",
    center: false,
    body: {
        view: "image"
    },
    loadImage: function(url, name) {
        this.set("caption", name);
        this.bodyContent.set("src", url);
        this.open();
    }
}, document.body);

When initializing UIkit components add data-uk-observe to the main <body> tag.

A list of UIkit components include:

  • autocomplete
  • dropdown
  • modal

Additionally, the upload attribute of any component also uses a UIkit component.

Defining new components

New UI components can be defined as so:

pykit.defUI({
    __name__: "canvas",
    $defaults: {
        htmlTag: "CANVAS"
    },
    $setters: {
        width: function(value) {
            this._html.width = value;
            return value;
        },
        height: function(value) {
            this._html.height = value;
            return value;
        }
    },
    __after__: function() {
        // Attach events or post-initialization stuff here
        // ...
        pykit.event(this._html, "change", this._onChange, this);
    },
    _onChange: function () {
        this.dispatch("onChange");
    },
    getSize: function() {
        return {width: this._html.width, height: this._html.height};
    },
    setWidth: function(value) {
        this.set('width', value);
    },
    setHeight: function(value) {
        this.set('height', value);
    }
});

Extending components

Any created components can inherit other components or be used to extend new components.

pykit.defUI({
    __name__: "toggleButton",
}, pykit.UI.button);

If multiple components are inherited, they will be extended in the order of right to left. Any methods with the same name will be overwritten by the left-most component in the extension list.

pykit.defUI({
    __name__: "toggleInput",
}, pykit.UI.input, pykit.UI.button);

Defining abstract extensions

For generic extensions, similar to Mixins, one can just define them as regular objects.

ClickEvents = {
    $setters: {
        target: function(value) {
            this._html.setAttribute("target", value);
            return value;
        },
        href: function(value) {
            this._html.setAttribute("href", value);
            return value;
        }
    },
    __after__: function(config){
        if (config.click) {
            config.on = config.on || {};
            config.on.onItemClick = config.click;
        }
        pykit.event(this._html, "click", this._onClick, this);
        pykit.event(this._html, "contextmenu", this._onContext, this);
    },
    _onClick: function(e){
        this.dispatch("onClick", [this, this._html, e]);
    },
    _onContext: function(e) {
        this.dispatch("onContext", [this, this._html, e]);
    }
};

// They can be used to extend components
pykit.defUI({
    __name__:"button",
    $defaults: {
        label: "",
        htmlTag: "BUTTON",
    },
    template: function(config) {
        return pykit.replaceString("<span>{label}</span>", {label: config.label});
    }
}, ClickEvents, pykit.UI.element);

Defining required extensions

When defining abstract components, one can add required extensions using __check__. An error will be thrown if components are not properly extended.

AbstractButton = {
    __name__: "AbstractButton",
    __check__: function(bases) {
        pykit.assert(bases.indexOf('AbstractButton') != -1, "AbstractButton is an abstract class and must be extended.");
        pykit.assert(bases.indexOf('AbstractClickable') != -1, "AbstractButton must extend AbstractClickable.");
    }
}

// This will throw an error
pykit.defUI({
    __name__: "button",
}, AbstractButton);

// This will work
pykit.defUI({
    __name__: "button",
}, AbstractButton, AbstractClickable);

Note that inherited classes can be accessed through the __bases__ attribute.

Using setters and defaults

Any JSON configurations that requires setters can be defined on the $setters object. To manually trigger the setter, use this.set(propName, value).

pykit.defUI({
    __name__: "button",
    $setters: {
        css: function(value) {
            pykit.html.addCSS(value);
        }
    }
});

Any default configurations should be defined on the $defaults object. To access configurations, one should use this.config.propName.

pykit.defUI({
    __name__: "button",
    $defaults: {
        css: "uk-button"
    },
    $setters: {
        css: function(value) {
            pykit.html.addCSS(value);
        }
    },
    __after__() {
        console.log(this.config.css);
    }
});

Initialization handling

Initialization of components takes place in __init__ and __after__.

pykit.defUI({
    __name__: "button",
    __init__: function() {
        // Should initialize variables used by this component here
        this._toggled = false;

        // HTML is not initialized
        console.log(this._html); // undefined

        // Dispatcher is not initialized
        console.log(this.dispatch); // undefined
    },
    __after__: function() {
        // Can register events, dispatch events, etc.

        // Add listeners to HTML tag
        pykit.event(this._html, "change", callback, this);

        // Add listeners to this component
        this.addListener("onInitialized", callback);
        this.addListener("onClick", callback);

        // Dispatch events
        this.dispatch("onCustomEvent");
    }
}, pykit.UI.element);

Standard components

A list of standard components can be found below.

  • autocomplete
  • button
  • dropdown
  • element
  • fieldset
  • flexgrid
  • form
  • icon
  • image
  • input
  • label
  • link
  • list
  • modal
  • password
  • search
  • table
  • tree

Standard attributes

Currently undocumented.

Demos

For a list of demos, see the layout_tests folder.

Developers

First of all, install Node. We use Gulp to build Pykit. If you haven't used Gulp before, you need to install the gulp package as a global install.

npm install --global gulp

If you haven't done so already, clone the Pykit git repo.

git clone git://github.com/zebzhao/pykit.git

Install the Node dependencies.

cd pykit
npm install

Run gulp to build and minify the release.

gulp
gulp build
gulp build-debug

Tests

All tests are contained in the tests folder. Tests can be run using npm test.

Contributing

Pykit follows the GitFlow branching model. The master branch always reflects a production-ready state while the latest development is taking place in the develop branch.

Each time you want to work on a fix or a new feature, create a new branch based on the develop branch: git checkout -b BRANCH_NAME develop. Only pull requests to the develop branch will be merged.

Browser compatibility

Pykit's flexgrid component relies heavily on flex containers and will not support any browsers not supporting flex containers. No effort has been made to support IE10-, as this would greatly complicate the current codebase.