Getting Started

Introduction

Asic is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Asic doesn't require any boilerplate code. Asic is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.

Instalation

via npm

bash

npm i asic --save
                    

via CDN

HTML

<script src="https://unpkg.com/asic"></script>
                    

Basic Usage

TypeScript

import { Component } from 'asic'

@Component({
    element: 'BasicUsage',
    template: `
<div>
    <p>My Component</p>
    <p>{{ text }}</p>
</div>`
})
export class BasicUsage {
    text = 'Some Text';
}
                    
HTML

<BasicUsage></BasicUsage>
                    

Basics

Data Biding

Data binding in Asic is the synchronization between the model and the view.

TypeScript

import { Component } from 'asic'

@Component({
    element: 'SimpleText',
    template: `<p>{{ text }}</p>`
})
export class SimpleText {
    text = 'Simple Text';
}
                    
HTML

<SimpleText></SimpleText>
                    

Composition

You can put one component into another.

TypeScript

import { Component } from 'asic'

@Component({
    element: 'ComplexComponent',
    template: `
<div>
    <p>Container</p>
    <SimpleText></SimpleText>
</div>`
})
export class ComplexComponent {
}
                    
HTML

<ComplexComponent></ComplexComponent>
                    

Events

You can add mouse events on any HTML element.

TypeScript

import { Component, Ref } from 'asic'

@Component({
    element: 'Events',
    template: `
<div>
    <p>Clicks counter: {{ count }}</p>
    <p>{{ login.value }}</p>
    <input type="text" #login (input)="increment()">
    <button (click)="increment()" (mouseover)="log()">click</button>
</div>`
})
export class Events {
    @Ref login;
    count = 0;

    increment() {
        this.count++;
    }

    log() {
        console.log('mouseover');
    }
}
                    
HTML

<Events></Events>
                    

Inputs

To pass data inside component use @Input decorator and pass data via component attributes.

TypeScript

import { Component, Input } from 'asic'

@Component({
    element: 'Props',
    template: `
<div>
    <p>{{ title }}</p>
    <ul>
        <li *for="item in items">{{ item }}</li>
    </ul>
</div>`
})
export class Props {
    @Input items;
    @Input title;
}
                    
HTML

<Props title="list of items" [items]="['hello', 'world']"></Props>
                    

Outputs

With @Output you can add custom events on any your component. It will be function which you can call with payload.

TypeScript

import { Component, Ref, Output } from 'asic'

@Component({
    element: 'MyComponent',
    template: `<button (click)="onClick()">Fire Event</button>`
})
export class MyComponent {
    @Output myCustomEvent;

    onClick() {
        this.myCustomEvent('some event payload');
    }
}

@Component({
    element: 'CustomEvents',
    template: `
<div>
    <p>Custom Events</p>
    <MyComponent (myCustomEvent)="alert($event)"></MyComponent>
</div>`
})
export class CustomEvents {
}
                    
HTML

<CustomEvents></CustomEvents>
                    

Loops

The *for directive repeats an HTML element

TypeScript

import { Component } from 'asic'

@Component({
    element: 'Loops',
    template: `
<ul>
    <li *for="item in items">
        {{ item }}
    </li>
</ul>`
})
export class Loops {
    items = ['javascript', 'python', 'ruby'];
}
                    
HTML

<Loops></Loops>
                    

Lifecycle

initialize is lifecycle hook. It calls after component is created. All async initialization should be performed here.

TypeScript

import { Component } from 'asic'

@Component({
    element: 'Lifecycle',
    template: `<p>Value: {{ count }}</p>`
})
export class Lifecycle {
    count = 0;
    initialize() {
        setInterval(() => {
            this.increment();
        }, 1000);
    }
    increment() {
        this.count++;
    }
}
                    
HTML

<Lifecycle></Lifecycle>
                    

Samples

Inner Loops

TypeScript

import { Component } from 'asic'

@Component({
    element: 'InnerLoops',
    template: `
<div>
    <p>Active skill: <strong>{{ activeSkill }}</strong></p>
    <ul>
        <li *for="item in items">
            <span>{{ item.name }} skills:</span><button *for="skill in item.skills" (click)="setActive(skill)">{{ skill }}</button>
            <SimpleText></SimpleText>
        </li>
    </ul>
</div>`
})
export class InnerLoops {
    activeSkill = '';
    items = [
        {name: 'John', skills: ['javascript', 'java']},
        {name: 'Adam', skills: ['python', 'ruby', 'html']}
    ];

    setActive(skill) {
        this.activeSkill = skill;
    }
}
                    
HTML

<InnerLoops></InnerLoops>
                    

Todo List

Todo list example

TypeScript

import { Component, Input, Ref } from 'asic'

@Component({
    element: 'TodoList',
    template: `
<div>
    <p>{{ title }}</p>
    <input type="text" #input>
    <button (click)="addItem()">Add</button>
    <ul>
        <li *for="item in items">
            <button (click)="removeItem(item)">remove</button>{{ item.name }}
        </li>
    </ul>
    <SimpleText></SimpleText>
</div>`
})
export class TodoList {
    @Input title;
    @Ref input;

    items = [
        {name: 'Improve Asic', done: false}
    ];

    addItem() {
        this.items.push({name: this.input.value, done: false});
    }

    removeItem(item) {
        this.items.splice(this.items.indexOf(item), 1);
    }
}
                    
HTML

<TodoList title="Todo List"></TodoList>