@ayu-sh-kr/dota-core is a web component library that provide API for creating and managing web components. With it's API one can reduce lots of boiler plate code used in creating a web component. It's a proxy and event driven library that automated event handling and component registration for user.
For creating web component we will start of our project on Vanilla Javascript and using Typescript
Installation
npm install @ayu-sh-kr/dota-core
Creating a web component
To create a component we will require to import @Component (decorator to register the web component) and abstract class BaseElement, this is minimum requirement to create a web component
import {BaseElement, Component, HTML} from "@ayu-sh-kr/dota-core/dist";
@Component({
selector: 'app-header',
shadow: false
})
export class AppHeader extends BaseElement {
render() {
return HTML`
<ul>
<li>Home</li>
<li>Menu</li>
<li>Service</li>
<li>Contact</li>
</ul>
`
}
}
Using the Component
To use the web component we must insure that it is registered and which will be taken care by the @Component decorator. Import the component file where you need, as module script in html file and import as file in your ts file.
import './app-header.component.ts'
document.getElementById('#app')!.innerHTML = `
<app-header/>
`
<body>
<app-header/>
<script type="module" src="./app.header.component.ts"></script>
</body>
Property Binding
Properties are very important aspect of web component, and they hold the state of the component. We provide value to the properties of the component as an attribute to the component. To bind the element attribute to it property we use the decorator @Property
import {BaseElement, Component, Property} from "@ayu-sh-kr/dota-core/dist";
@Component({
selector: 'property-example',
shadow: false
})
export class PropertyExample extends BaseElement {
@Property({name: 'data'})
data!: string;
render() {
return `
`
}
}
<property-example data="Some Value"/>
Method calling
You should be wondering how can we call methods with this style of component creations. As the Dota-Core uses Vanilla Js under the hood you can call method by binding them to their called element.
To bind a method we use event binding.
let element = document.getElementById('#id');
element.addEventListener('click', () => {
console.log('clicked')
})
Dota-Core working on the above principle provides a very neat way to bind events to the method. They provide @BindEvent decorator to achieve the same, just decorate the method you want to bind and event to and provide the event and id as object to it. Also give the element that you want to bind the event an id
import {BaseElement, Component, HTML, BindEvent} from "@ayu-sh-kr/dota-core/dist";
@Component({
selector: 'reactive-click',
shadow: false
})
export class ReactiveClick extends BaseElement {
@BindEvent({event: 'click', id: '#button'})
handleClick() {
console.log('Clicked')
}
render() {
return `
<button id="button">Click Me</button>
`
}
}
Event Emitter
Event is very important aspect of any component not just the web component, through events components communicate and update their state. To deal with events, Dota-Core provides EventEmitter class to emit custom events.
Event emitted can be of two level.
- Window (Global Scope)
- Root (Component Scope)
To Emit events we first need an EventEmitter object which can be initialized with a decorator or directly
import {EventEmitter, BaseElement, Event} from "@ayu-sh-kr/dota-core/dist";
export class EventExample extends BaseElement {
@Event
event!: EventEmitter<string>
}
OR
import {EventEmitter, BaseElement, Event} from "@ayu-sh-kr/dota-core/dist";
export class EventExample extends BaseElement {
@Event
event! = new EventEmitter('onEvent');
render() {
return `
`
}
}
Example of the EventEmitter
import {BaseElement, Component, EventEmitter, Event} from "@ayu-sh-kr/dota-core/dist";
@Component({
selector: 'emit-example',
shadow: false
})
export class EmitExample extends BaseElement {
@Event
change!: EventEmitter<string>
@BindEvent({event: 'click', id: '#button'})
emitEvent() {
this.change.emit('data', this) // event is root level
this.change.emit('data') // event is global scoped
}
render() {
return `
<button id="button">Click Me</button>
`
}
}
Event Listeners
When a component emits some event then it should be listened by some other components. Listening to event similar to Binding the event to a method which will react to certain occurrence of the event.
To make method listen to some event we will decorate it with @EventListener which takes an object stating event name and event type
import {BaseElement, Component, EventListener} from "@ayu-sh-kr/dota-core/dist";
import './emit-example.component.ts'
@Component({
selector: 'listen-example',
shadow: false
})
export class ListenExample extends BaseElement {
@EventListener({name: 'onChange', type: EventType.ROOT})
listenEvent() {
console.log('Do Something')
}
render() {
return `
<emit-example/>
`
}
}