air-m2 v0.7.5
m2
Inline plugging
view plugin
the simplest plug-in has the form:
<unit>
<view-source> import { stream } from "m2"
export default ({ source/*, targets */}) => {
return stream( (emt, { over }) => {
over.add(source.on((evt, src) => {
emt(evt, src);
}));
} );
} </view-source>
</unit>you can access nested nodes and modify them
<unit>
<view-source> import { stream } from "m2"
export default ({ source, targets: [ { node } ] }) => {
const inner = node.querySelector("[custom-plugin-inner]");
return stream( (emt, { over }) => {
over.add(source.on(emt ));
inner.textContent = 77;
} );
} </view-source>
<div>
<span custom-plugin-inner>custom-value</span>
</div>
</unit>stream plugin
you can also modify the data stream before use:
<unit>
<stream-source> import { stream } from "m2"
export default ({ obtain }) =>
obtain().map( data => [data] ) </stream-source>
</unit>View engine
Simple
Templates definition
data transmission from events
<span>`${property}`</span>the event source must have the form
[{property: 77}]the data source can be an object with a nested structure
<span>`${somefield.nested}`</span>[{somefield: {nested: 77} }]formatting
if you provide number settings, you can use formatting:
<span>`${intl.formatter-resource-name(value)}`</span>,where {formatter-resource-name} - data transmission template
the event source must have the form
[{property: 77}]formatting resource file example:
[
"formatters",
["currency", { "style": "currency", "splitter": ".", "currencyDisplay": "symbol" }],
["compact-currency", { "style": "currency", "splitter": ".", "currencyDisplay": "symbol",
"minimumFractionDigits": 0
}],
["number", { "style": "decimal", "splitter": "." }],
["percent", { "style": "percent" }]
]localization
if you supply localization resources you can use automatic literal substitution:
<span>`${lang.localization-string-resource-name}`</span>localization resource file example:
<?xml version="1.0" encoding="utf-8"?>
<languages>
<en>
<string name="example-literal-string">Example literal text content</string>
<string name="example-literal-string-2">Example literal text content 2</string>
</en>
<ru>
<string name="example-literal-string">Пример случайной строки</string>
<string name="example-literal-string-2">Пример случайной строки 2</string>
</ru>
</languages>Actions definition
Animation
<keyframe [name = default] [prop = {easing:"linear",duration:5}] >
<key [offset = 0] prop = {scale:0}></key>
<key [offset = 1] prop = {scale:1}></key>
</keyframe>inline fade-in fade-out supported
<keyframe name = fade-in [duration = 5]>
<key [offset = 0] prop = {translateX:0}></key>
<key [offset = 1] prop = {translateX:100}></key>
</keyframe>binding data from stream
<keyframe name = fade-in [duration = 5]>
<key prop = {scaleX:(x)}></key>
</keyframe>[{x: 1.5}]Inline (local) CSS styles & SASS
<unit>
<style [type="text/scss"]> <!-- to enable SASS processing --> body { /* global selector */
padding: 0;
margin: 0;
}
:scope { /* local selector */
width: 100%;
background-color: #0026ff;
height: 100%;
} </style>
<div></div>
</unit>Class controllers
<keyframe>
<key prop = {classList:{active:(isactive)}}></key>
</keyframe>[{isactive: true}]or
<keyframe>
<key prop = {classList:{red|green|black:(selectedColor)}}></key>
</keyframe>[{selectedColor: "red"}]Sound controls
<keyframe name="animation-name">
<key prop={sound:'sound-name'}></key>
</keyframe>Sound will be played once
or
<keyframe name="animation-name" prop="{duration: 2}">
<key offset="0.2" prop={sound:'sound-name'} ></key>
<key offset="0.7" prop={sound:'sound-name'} ></key>
</keyframe>Sounds will be played 2 times with certain offsets and will be stopped if duration of animation less than duration of sounds
, where
sound- name of resource declared in<sound>tag
Sound resource declaration
<sound name="sound-name" rel="sound-resource"></sound>, where
name- name of resourcerel- file name without extension from the directorycomponent/res/sounds/sound-resource
if you want to use the general sounds for components, you can go up the nesting levels
rel="../../sound-resource"
Reactions definition
<unit onclick = req("action-name",{/*args*/})></unit>where environment variables:
- req - stream fallback method
- key - view-component name
- options - current view-component options
- event - system event data
List of supported events
"onclick""onclickoutside" (synthetic)"onpointermove""onpointerenter""onpointerleave""onpointerup""onpointerdown""onmouseenter""onmouseleave""onmouseover""onmouseout""onchange""oninput""onglobalkeydown" (synthetic)"onglobalkeyup" (synthetic)"onkeydown""onkeyup""onwheel""onscroll"also supported custom events
"on:custom-event"
<view-source>import { stream } from "m2"
class MyEvent extends Event {
constructor() {
super("my-event");
this.myData = 100;
}
log() {
console.log("check", this);
}
}
export default ({ source, targets }) => {
return stream( (emt, { over }) => {
over.add(source.on((evt, src) => {
setTimeout( () => {
targets[0].node.dispatchEvent(new MyEvent());
}, 1000);
emt(evt, src);
}));
} );
}</view-source>
Switcher
selects one view state available according to the model.
<unit tee = {a:10,b:-1}></unit>rendered to the page if the condition when mapping data from the stream is fully met
[{a: 10, b: -1, ...other}]or not rendered
[{a: 10, b: -2, ...other}]allowed to use attachments and abbreviated forms
<unit tee = {obj:{prop}}></unit>[{obj: {prop: 1}}]functional form is also now supported
<unit tee() = "obj.prop > 0"></unit>[{obj: {prop: 1}}]you can even use a static form
<unit tee() = 1></unit>however, the view component will still wait for the model stream
Common features
Coupling with model
you can link your view to the stream to get actions and process reactions
<unit stream = ./path>any relative path will be calculated relative to the parent view, which is related to the model.
you can use the constant $name as a parameter to pass the current name of the view to the model
<unit stream = ./path/to/model[key=$name]>Submodules
you can use the included submodules
<unit use = url(./path-to-src-module)></unit>or
<unit use = ./path-to-registered-module></unit>Model unit
each model is a function that returns a stream:
it is a new stream
import { stream } from "m2"
export default ( { /*...args*/ } ) =>
stream(emt => {
emt( "something" );
}), where
- stream - "air-stream" object "stream"
or an existing converted stream
import { stream } from "m2"
export default ( { obtain, /*...args*/ } ) =>
obtain("../some/existing-stream/path")
.map( count => count + 1 )
.controller(
obtain("../some/existing-stream-controller/path"),
({action}) => ({ action, data: "ok" })
), where
- obtain - method of accessing an existing model from the schema
- args - init options that were specified when accessing the stream
can be specified in the "obtain" method
obtain("./path", { argv: 10 })or right on the path
obtain("./path[argv=10]")Paths
the simplest path has the form:
"./cat-a/cat-b/cat-c"
Supported features
"./cat-a"- entry to the directory"./"- current directory"../"- parent directory"./{name: abc, kind: 10}"- directories with a complex name"./cat-a[kind=10]"- passing arguments"./#component-id"- search by id"./@component-key"- search by key
Note: when using search by id or key it begins from parent layer and move upward until root layer. So, sometimes you MUST specify exact path to model
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago