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
- Template
- State
- Attrs
- Template
- Dynamic output
- Event Listener
- Refs
- Directives
- loopArray
- Lifecycle
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 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 (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 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>
`;
}
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.
{{ dynamic_value }}
class App extends Widget {
state = {
userName: "John Garrett"
};
template = `
<p>Hello {{ this.state.userName }}</p>
<p>Now it is {{ new Date().toDateString() }}</p>
`;
}
Hello John Garrett
Now it is Fri Jan 08 2021
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.
<element [attributeName]="dynamic_value"></element>
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.
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.
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.
<element :eventType="callbackFunction"></element>
class App extends Widget {
template = `
<button :click={this.sayHello}>Click here</button>
`;
sayHello() {
window.alert('Hello world!');
}
}
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.
<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> |
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 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. |
<any-element :directiveName="value"></any-element>
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
helps to loop through an array. This can be used only with custom widgets to improve the better writing of code.
<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.
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>
`;
}
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 |