A mini JavaScript Library for reactive UI components
View on GitHubPopcornJS is a mini JavaScript library that is aimed at tackling lightweight reactive UI components. How will you benefit from PopcornJS? Imagine all the big libraries or frameworks out there running on webpacks, with NodeJS services running on the backend; would you really need those for a simple application? Or, would you really like to rewrite your entire application’s frontend just for some added features?
Guess not, hence you stumble upon this library.
Let’s get started. How do you use PopcornJS? Simple.
class ExampleComponent extends Popcorn{
render(){
return(
`
<p>Hello ${this.state.message}</p>
`
)
}
}
<script>
<html>
<body>
<div class="content"></div>
<script>
let input = new ExampleComponent('.content');
</script>
</body>
</html>
Your component is now ready and rendered into your HTML page.
If you want to get event-triggered functions, it will be slightly different from the usual convention. You would need to use kernels. A popcorn’s prior state is a kernel… get it? So first off, get your kernel ready, before you can start popping.
class Input extends Popcorn{
loadKernel(){
return {
inputFn: (text) => {
console.log(text);
},
}
}
render(){
return `<input oninput="kernel.inputFn(this.value)">`
}
}
Load up the loadKernel
method, and return object-based functions with it. Take note how the oninput is written to include the kernels. Now it’s ready. Give it a try yourself.
Yes! Else how would it be reactive?
You can choose to, or not to. Entirely up to you, really. Do so if you need initial states for some magic.
let exampleComponent = new ExampleComponent('.content',{
message: 'Hello World',
data: ['This', 'Is', 'PopcornJS']
});
Really simple. Everything is in this.state
.
class ExampleComponent extends Popcorn{
render(){
let dataStr;
for(var i=0; i<this.state.data.length; i++){
dataStr += `${this.state.data[i]} `
}
return(
`
<p>Hello ${this.state.message}</p>
<p>${dataStr}</p>
`
)
}
}
exampleComponent.setState({
message: "Bye World",
data: ['I', 'Shall', 'Sleep']
})
What if you need components, within a component? Just get it in, what else?
Things to take note:
createDOM()
methodclass ParentComponent extends Popcorn{
render(){
let list = "";
for(let i=0; i<this.state.data.length; i++){
list += `<li>${this.state.data[i]}</li>`
}
return(
`
${new ChildComponent(this.state).createDOM()}
<ul>
${list}
</ul>
`
)
}
}
Take note on how you can pass the states to the child component(s).
class ChildComponent extends Popcorn{
render(){
return(
`
<p>Hello ${this.state.message}</p>
`
)
}
}
Ever find the usefulness of compartmentalised JS? To keep it completely separated from each other, that is. To do so, we should also split our CSS and contain them to its own components, or not. It is entirely up to you really.
Things to take note:
this.classes
is used to assign class names to each elementloadCSS()
method, and how it is written in JSON.class Input extends Popcorn{
loadCSS(){
return {
".input": {
"font-size": "30px",
"border-color": "white"
}
}
}
render(){
return `<input class='${this.classes.input}'>`
}
}
At times you may want to trigger some actions on component load status. These are built in and is as such:
willBeRendered()
(Fired just as the component is ready to load the UI)hasRendered()
(Fired after UI is pushed to the view)willRerender()
(Fired when states are about to get updated)hasRerendered()
(Fired after states got updated)class Input extends Popcorn{
willBeRendered(){
alert('I am about to be rendered');
}
hasRendered(){
alert('I am rendered');
}
willRerender(){
alert('My state has just been changed, and I will be rerendered');
}
hasRerendered(){
alert('I have rerendered');
}
render(){
return `<input class='${this.classes.input}'>`
}
}