UI component self configuration

Zebkit UI components apply default properties values during its instantiation. The default properties values are read from static context of appropriate UI component class or from a parent class (if it has been configured). For instance, to change color of all subsequent “zebkit.ui.Label” component instances set appropriate property on label component class level:

// specify default label color value in label class static context  
zebkit.ui.Label.color = "orange";
...
// all label instances will have color set to "orange"
var lab1 = new zebkit.ui.Label("Label 1");
var lab2 = new zebkit.ui.Label("Label 2");
...

By default properties values defined on parent class level are not applied to an instance of a class that inherits the parent class. To change the behavior do the following:

// zebkit.ui.TextField class inherits zebkit.ui.Label
// class. To take in account label default properties 
// let's set "inheritProperties" to true 
zebkit.ui.TextField.inheritProperties = true;
...
// specify default label color value in label class static context 
zebkit.ui.Label.color = "orange";
...
// text field component instances will have color set to "orange"
var tf1 = new zebkit.ui.TextField("Text field 1");
var tf2 = new zebkit.ui.TextField("Text field 2");

Configuration resources

By default UI configuration JSON files are stored on the same level with zebkit UI components JS file(s) in “rs” sub-folder. The structure of zebkit UI configuration resources are shown below:

[rs]                      # root resource folder
 +-- [light]              # light theme resources folder
 |     +--  ui.json       # zebkit.ui package configuration  
 |     +--  ui.web.json   # zebkit.ui.web package configuration
 |     +--  ui.tree.json  # zebkit.ui.tree package configuration
 |     +--  ui.grid.json  # zebkit.ui.grid package configuration
 +-- [dark]               # dark theme resources folder
 |     +--  ui.json
 |     +--  ui.web.json
 |     +--  ui.tree.json
 |     +--  ui.grid.json
 |
 +-- ui.common.json

Loading JSON configurations setups static fields for appropriate package entities (classes, interfaces, etc) that will be later used as default properties values for the entities instances. Configuration Zebkit keeps JSON configuration per package (if necessary). It is also possible to load a custom configuration manually with “configWith([path])” method. For instance, imagine we have created JSON shown below to customize text field component properties:

{
    ...
    "TextField" : {
        "border"    :{"@zebkit.draw.Border":["red", 2]},
        "color"     :"white",
        "background":{"@zebkit.draw.Gradient":["red","orange"]}
    }
}

To apply the JSON do the following:

zebkit.ui.configWith("/tf.json");

Pay attention the way zebkit looks up for a required JSON :

Theme configuration

By default zebkit expects a theme resources are located in appropriate sub-folder in “rs”. To switch UI theme set “theme” configuration variable (that has to match a sub-folder hosted in “rs” folder):

// say to use light theme
zebkit.ui.config("theme", "light");

In a case if zebkit theme is located in other place specify base directory where the theme resources are stored:

// define path to custom theme    
zebkit.ui.config("basedir","http://test.com./myfolder/mytheme");

If there are number of themes you need to host in a custom place specify “basedir” as follow:

// define path to light theme    
zebkit.ui.config("basedir","http://test.com./myfolder/%{theme}");
...
// specify theme to be used
zebkit.ui.config("theme", "mytheme1");

Note: Note that configuration variables (theme, base directory, etc) have to be adjusted outside of “require” or “package” zebkit sections. The customization should look something like the following:

<script>
    // adjust theme variable
    zebkit.ui.config("theme","light");

    zebkit.require("ui", function(ui) {
        // develop UI 
        ...
    }); 
</script>

Zson as form descriptive language

JSON format is handy and clear way to declare various configurations, transfer data between clients and servers, etc. Zebkit extends JSON format interpretation with number of powerful features what allows developers to use it for UI form definition.

To load the JSON UI definition the following code can be used:

zebkit.require("ui", function(ui) {
    // load root component content with "simple.json" file
    new ui.zCanvas(400, 300).root.load("simple.json");
});

For example, let’s load the following Zson:

{
    "layout": { "@zebkit.layout.StackLayout" : []},
    "kids"  : [{
        "@zebkit.ui.Panel": [],
        "layout" : { "@zebkit.layout.BorderLayout" :4 },
        "padding": 4,
        "border" : "plain",
        "kids"   : {
            "top": {
                "@zebkit.ui.BoldLabel": "Simple application",
                "padding"             : 4
            },
            "center": { "@zebkit.ui.TextArea": "" },
            "bottom": {
                "@zebkit.ui.Button": "Clear",
                "canHaveFocus"     : false
            }
       }
    }],
    "#actions" : [{
        "source"  : "//zebkit.ui.Button",
        "target"  : {
            "path"   : "//zebkit.ui.TextArea",
            "update" : { "value": "" }
        }
    }]
}

The result of the loading is shown below:

JSON UI

A you can see there is “#actions” section in the JSON shown above. The section allows developers to declare simple events handling. In this particular case the section says to empty text area component value by button click. Full supported features of the section are shown below:

JSON element Description
"#actions.source" Path to identify a source component that fires an event(s)
"#actions.event" Optional an event name that has to be handled from the source
"#actions.condition" Optional a condition the source event is handled. Condition is dictionary of source properties and its values. If all properties values of the specified condition match the correspondent properties of source component the event will be handled.
"#actions.targets" or
"#actions.target"
List of targets ("#actions.targets") components or single target ("#actions.target") component to be updated by the source event(s)
"#actions.target.path" Path to detect a target component
"#actions.target.condition" Optional a condition the target "update" and "do" sections will be applied. Condition is dictionary of target properties and its values. If all properties values of the specified condition match the correspondent properties of target component "update" and "do" sections are applied to the target.
"#actions.target.update" Properties set the target has to be updated
"#actions.target.do" Set of actions over the target component

Composing Zson

Zson can be composed from multiple JSONs. Zson guarantees everything is loaded in a order it is mentioned in Zson, so you can safely add references to variables located in external JSONs if the reference appears later.

To combine multiple JSONs:

{
    "%{../external1.json}": "",
    "%{../external2.json}": "",
    "key" : {
        ...
    }
}

Or you can fulfill a value with the given JSON as follow:

{
    "key" : "%{../external.json}"
}

For example let use slightly modified JSON from previous UI example to populate the same UI four times:

{
    "@zebkit.ui.Panel": [],
    "layout": { "@zebkit.layout.StackLayout" : []},
    "kids"  : [{
        "@zebkit.ui.Panel":[],
        "layout" : { "@zebkit.layout.BorderLayout" :4 },
        "padding": 4,
        "border" : "plain",
        "kids"   : {
            "top": {
                "@zebkit.ui.BoldLabel": "Simple application",
                "padding"             : 4
            },
            "center": { "@zebkit.ui.TextArea": "" },
            "bottom": {
                "@zebkit.ui.Button": "Clear",
                "canHaveFocus"     : false
            }
       }
    }],
    "#actions" : [{
        "source"  : "//zebkit.ui.Button",
        "target"  : {
            "path"   : "//zebkit.ui.TextArea",
            "update" : { "value": "" }
        }
    }]
}

Find JSON to load external JSON mentioned above four times below:

{
    "layout" : { "@zebkit.layout.GridLayout": [2, 2, true, true] },
    "kids"   : [
        "%{./simple.json}",
        "%{./simple.json}",
        "%{./simple.json}",
        "%{./simple.json}"
    ]
}

The result is the application below:

Combining JSONs