Skip to content

artifishional/air-m2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 resource
  • rel - file name without extension from the directory component/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"

    Creating and triggering events in JavaScript

<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

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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages