UNPKG

neft

Version:

Universal Platform

394 lines (292 loc) 7.75 kB
# Views Integration Neft uses his own language to describe how the elements looks like, therefore styles in Neft can be well organized and more dynamic, because the JavaScript support, views data-binding and more. All style files must be placed in the `/styles` folder. ## NML syntax NML *(Neft Marked Language)* is a simple but powerful language inspired by QML. ```javascript TypeName { id: optionalItemId property: 'value' // comment namespace.property: 'value' onEvent: function(){ } // children TypeName { } } ``` `TypeName` is a class name provided by Neft: an Item, Column, Rectangle, FontLoader and more. `TypeName` can be also a reference to your custom style. `id` is optional and it's used for data-binding. ## Main style The main style must be returned as a first element from the `__view__.js` file. It's a starting point of your application. ## Base item All visible types in Neft extends the `Item` type. It contains various properties (e.g. `x`, `y`, `scale`, `width`, `nextSibling`), `keys` and `pointer` support, `children` list and more. Check later the API Reference for the `Renderer` module. ```javascript Item { width: 100 height: 100 scale: Math.PI / 2 } ``` ## Style file Style file can contains custom JavaScript code and top level items (items with no parent). ```javascript // styles/button.js ` var utils = Neft.utils; ` Item { id: button } Rectangle { id: squareButton } ``` ## Data binding Item properties can reference to the item object itself (`this`), other items (by their ids), defined JavaScript variables and call functions. ```javascript Item { x: Math.random() y: this.x width: child.width * 2 Rectangle { id: child width: 100 } } ``` `parent`, `previousSibling` and `nextSibling` don't have to be prefixed by `this`. ## Global access In style files you have access to the `app` object and to the `view` main style globally. ```javascript Rectangle { width: view.width color: app.cookies.clientColor } ``` ## Signals Renderer emits signals in various places: - on property value change (`onWidthChange(oldValue)`), - on namespace property change (`onMarginChange(property, oldValue)`), - on children change (`onChildrenChange(added, removed)`), - on pointer click (`pointer.onClick(event)`), - and more... Items with defined ids are available in the signal listener. ```javascript Item { width: 100 height: 100 pointer.onClick: function(event){ this.x = event.x; rect.color = 'green'; } Rectangle { id: rect width: 100 height: 100 color: 'red' } } ``` ## Conditions ```javascript Rectangle { x: 50 color: 'red' if (this.x < 70 && Device.mobile){ color: 'green' } } ``` ## Custom properties ```javascript Item { property $.health: 100 signal $.onAttack signal $.onLowHealth $.onAttack: function(target){ this.$.health -= target.$.attack; if (this.$.health < 40){ this.$.onLowHealth.emit(); } } } ``` Custom properties and signals must be created in the `$` object. Custom properties have their corresponding signals (e.g. `$.onHealthChange`). ## Type extending Top level objects are available in the `exports` object under their ids. ```javascript Item { id: button } exports.button { width: 100 } ``` This also works across files. ```javascript // styles/button.js Item { id: sampleButton } // styles/complexButton.js `` var button = require('./button.js'); `` button.sampleButton { } ``` ## Layout To position children in an item, you can use few methods: - absolute positioning (`x` and `y` properties), - from left to right - `Flow` type, - on a grid - `Grid`, `Column`, `Row` types, - anchors. ### Flow Flow element position items from left to right. ```javascript Flow { width: 400 Rectangle { width: 100 height: 100 margin.bottom: 20 } Rectangle { layout.fillWidth: true } } ``` ### Grid Grid positions its children in a grid formation. Other elements similar to `Grid` are `Column` and `Row`. ```javascript Grid { columns: 2 spacing: 20 Rectangle { width: 100 height: 100 } Rectangle { width: 100 height: 100 } } ``` ### Anchor `Item::anchor` describes relation between two items. Each item has few lines: top, verticalCenter, bottom, left, horizontalCenter and bottom. You can stick an item line into another item line. For the performance reasons, you can anchor only to siblings or to the item parent. ```javascript Item { Rectangle { id: rect1 } Rectangle { anchors.left: rect1.right margin.left: 20 } } ``` ## Background `Item::background` gives a possibility to use any item as a background. By default, *background` is a `Rectangle` filling his parent. ```javascript Item { background: Rectangle { color: 'red' } // .. or just background.color: 'red' } ``` ## Number animation Neft supports animating number properties. Use `NumberAnimation` to achieve this goal. By default animator animates item, in which it was created. ```javascript Item { NumberAnimation { property: 'x' from: 0 to: 1000 loop: true } } ``` By default animators don't update the property during animation (it's much faster). To change this behaviour, switch the `PropertyAnimation::updateProperty` boolean. ## Transitions Transition type automatically animate all updates on the given property. ```javascript Item { width: 205 if (this.pointer.hover){ x: 100 } Transition { when: this.target.width > 200 property: 'x' animation: NumberAnimation { startDelay: 500 easing: 'OutSine' } } } ``` ## Views integration You can draw styles just putting them into the `__view__.js` top level item, but, for the better organization, we need to integrate our HTML documents with created styles. `Item::document::query` will use an item on all elements found by the given query. `document::query` can't be changed in runtime. ```javascript Text { document.query: 'span' // this item will be used for all 'span' elements from views } ``` Because the `document::query` can be also attached to the item children, you can create complex custom elements based on more than one HTML elements ```javascript Item { document.query: 'avatar' Text { document.query: '> nick' } } ``` ### Runtime changes For more dynamic behaviors you can use the `for (query) {}` syntax. It works like `if () {}` but uses a query and modifies all found HTML elements in runtime. ```javascript for ('header.large'){ width: parent.width * 0.8 } ``` `for` can be a top level definition or an `Item` children. `for`s can be nested. ```javascript for ('body[page=docs]'){ for ('header'){ background.color: 'green' } } ``` ### Text styling All HTML texts are rendered by default as Renderer `Text` items. You can modify how the texts looks like using the `#text` query. In Neft, text styles are not inherited like in CSS. ```javascript for ('span.large #text') { font.pixelSize: 30 } ``` ### Inline styles Attached style Item on the document element is available under the `style` property. You can use it to define inline styles in the HTML document. ```html <span style:font:pixelSize="30">ABC</span> ``` Inline styles also supports signals. ```html <span style:pointer:onClick="${this.onSpanClick}">ABC</span> ``` Next article: [[Networking - Tour]]