Core concepts - siddeshwarnavink/kyte GitHub Wiki

These are the concepts that you need to understand. Don't worry, these concepts are just a matter of terms if you have already worked with any Javascript framework.

Widget basics

Widget is the basic building block of a Kyte project. Widgets are the individual pieces of the website which makes the whole webpage. These widgets may scale up from a small button as a widget to the entire page as a single widget.

A widget can be created using Kyte.js by

class MyWidget extends Widget {
    // ...
}

To see the widget in action, it has to be mounted to the DOM.

import Kyte from 'kyte-js';

// ...

new Kyte({
    mount: new MyWidget(),
    root: '#app'
});

Now this mounts the widget to an element with ID app, like for example

<div id="app"></div>

Now let us see the properties of a Widget.

State

State is the internal value of the Widget which determines how the widget should be displayed. For example

class MyWidget extends Widget {
    state = {
        userName: 'John doe',
        displayInfo: false
    }

    // ...
}

In this example, we can see the displayInfo is false. According to this, we can manipulate the template and show different output. We can see how that can be done in the dynamic output section.

We can update the value in the state by using updateState function

class MyWidget extends Widget {
    // ...

    toggleDisplay = () => {
        this.updateState(() => {
            this.state.displayInfo = !this.state.displayInfo;
        });
    }
}

Attrs

Attrs (or) Attributes are the data that passed from the parent component to the child component which pretty much helps in determining how the component is expected to render. These attrs can be simply passed just like an HTML attribute. For example,

Parrent component is simply the component which mounts the required children components on itself. We can see this in-detail on custom widgets section.

<my-widget userName="John doe"></my-widget>
<my-widget userName="Jane doe"></my-widget>

We can receive the value of all the attrs as attrs property in the widget.

class MyWidget extends Widget {
    // ...

    logUsernameHandler = () => {
        console.log(this.attrs.userName);
    }
}

If these things sound confusing, don't worry, It'll become more clear when it is co-related with other upcoming concepts.

Template

Template is the basically the content of the widget that is displayed to the DOM. This is just a string. All the HTML tags are valid.

class App extends Widget {
    template = `
        <h1>Hello to Kyte.js</h1>
    `;
}

Dynamic output

String interpolation

String interpolation is a way to display dynamic content to the template. This mostly works with State and Attrs but it's not restricted to that.

Syntax

{{ dynamic_value }}

Example

class App extends Widget {
    state = {
        userName: "John Garrett"
    };
    
    template = `
        <p>Hello {{ this.state.userName }}</p>

        <p>Now it is {{ new Date().toDateString() }}</p>
    `;
}

Output

Hello John Garrett

Now it is Fri Jan 08 2021

Dynamic attrs

Dynamic attrs are similar to String interpolation but except they help in passing dynamic values as an attribute to either a native HTML element or to a custom widget.

Syntax

<element [attributeName]="dynamic_value"></element>

Example

class App extends Widget {
    state = {
        maskPassword: true
    };
    
    template = `
        <input [type]="this.state.maskPassword ? 'password' : 'text'" />
        <button :click={this.togglePassword}>Toggle password</button>
    `;

    togglePassword = () => {
        this.updateState(() => {
            this.state.maskPassword = !this.state.maskPassword;
        });
    }
}

That :click attribute is an event listener which triggers the function when the given event occurs. Learn more in Event listener section.

Custom widgets

A widget can be also mounted in another widget's template. In this case, the widget which is being mounted is called as child widget and the widget which is mounting the child widget on itself is called a parent widget. In order to use a custom widget, the widget must be registered to widgets object of the component with the key as the 'tag name' and the value as the object of the widget. For example,

class MyWidget extends Widget {
    template = `
        <p>Hello {{ this.attrs.userName }}.</p>
    `
}

class MyParrentWidget extends Widget {
    widgets = {
        'user-widget': MyWidget
    };

    template = `
        <user-widget userName="John deo"></user-widget>
        <user-widget userName="Nathen deo"></user-widget>
    `;
}

On mounting the MyParrentWidget to the DOM, we get the following output.

Hello John deo.

Hello Nathen deo.

Now, this may give a clear idea that how powerful the widgets are and clearly makes them a basic building block of Kyte.js project.

Event Listener

An event listener is a reserved attribute which helps to listen to events of the DOM element or the custom widget it is being used on.

Syntax

<element :eventType="callbackFunction"></element>

Example

class App extends Widget {
    template = `
        <button :click={this.sayHello}>Click here</button>
    `;

    sayHello() {
        window.alert('Hello world!');
    }
}

Refs

Refs (or) Reference in case of a custom widget, gives the Widget`s instance or in case of a native HTML element, gives the DOM reference of the element.

Syntax

<element ref="refName"></element>

You can access the array of all the refs as a property named ref of the widget where it is being used. Each ref object is just a regular Javascript object with the following properties.

Property Description Datatype
dom Reference of the DOM element HTMLElement
isCustomWidget Whether this ref is for a custom widget or not Boolean
widget The current instance of the widget <Widget|null>

Example

class App extends Widget {
    state = {
        pageTitle: "Hello world"
    }

    template = `
        <h1>{{ this.state.pageTitle }}</h1>
        <input ref="inputRef" value="New title" />
        <button :click={this.changeTitle}>Change title</button>
    `;

    changeTitle = () => {
        this.updateState(() => {
            this.state.pageTitle = this.refs.inputRef.dom.value;
        });
    }
}

Directives

Directives are special instructions given to an HTML element or a custom widget which can change how is being displayed to the user. They are prefixed with :

Directive Description
if It takes a condition as its value. If the condition is false, the element will be removed from DOM. If it is true, it'll be re-added if the condition is true.
hide It takes a condition as its value. If the condition is false, the element hidden from DOM. If it is true, it'll be re-displayed if the condition is true.

Syntax

<any-element :directiveName="value"></any-element>

Example

class MyApp extends Widget {
    state = {
        display: false
    };

    template = `
        <span :if="this.state.display">Magic!</span>
        <span #click={this.showSpan}>Surprise</span>
    `;

    showSpan() {
        this.updateState(() => {
            this.state.display = true;
        });
    }
}

loopArray EXPERIMENTAL

loopArray helps to loop through an array. This can be used only with custom widgets to improve the better writing of code.

Syntax

<loop-item-widget loopArray="arrayToList"></loop-item-widget>

The individual loop item widget receives two special attrs

  • loopItem: The value of the array of the iteration.
  • loopIndex: The current iteration count.

Example

class TodoItem extends Widget {
    template = `
        <li>{{ this.attrs.loopItem }}</li>
    `
}

class App extends Widget {
    widgets: {
        'todo-item': TodoItem
    }

    state = {
        todos: [
            'Have coffee',
            'Learn Kyte.js'
        ]
    }

    template = `
        <ul>
            <todo-item loopArray="this.state.todos"></todo-item>
        </ul>
    `;
}

Lifecycle

There are three lifecycle methods which you can use,

Lifecycle Attributes Description
onMount() - Runs when the widget is being mounted initially
onStateChange() oldState, newState Runs when the state is changed
onAttrsChange() oldAttrs, newAttrs Runs when the attrs are changed
⚠️ **GitHub.com Fallback** ⚠️