H12 is a lightweight(3kb) javascript front-end library inspired from ReactJS, that allow using components which can use used around multiple places.
import H12 from "@library/h12";
class App extends H12 {
constructor() {
super();
}
main() {}
render() {
return <>
<div>
Hello world
</div>
</>;
}
}
document.body.appendChild(new App().init());
-
-
In H12, every tag, whether it’s a component or an HTML element, should be encapsulated within
<>
and</>
, also known as a fragment. This allows you to return multiple elements or components from the render method without adding extra nodes to the DOM.render() { return <> <div>Hello world</div> </> }
-
You can also store templates in variables. This is useful for organizing complex templates or reusing parts of a template across different methods.
myTemplate() { const btn = <><button>Click</button></> const icon = <><Icon args src="home.png"></Icon></> }
-
In H12, every tag, whether it’s a component or an HTML element, should be encapsulated within
-
Every component should have a
args
attribute. Components rely on this attribute to receive parameters and render correctly. Withoutargs
, the tag is interpreted as a standard HTML element, and any component-specific behavior or functionality will not be applied.-
render() { return <> <div> <Icon args></Icon> </div> </>; }
-
The passed values like
altText
andsrc
can be accessed inIcon
class using thethis.args
property.render() { const text = "Home"; return <> <div> <Icon args src="home.png" alttext={ text }></Icon> </div> </>; } // inside Icon // this.args.src, this.args.altText or // const { src, altText } = this.args;
-
The H12 components follows a hierarchy, each component have a
parent
andchild
property, which can be used to traverse along the components. You can assign a unique id to the component using theid
attribute.render() { return <> <div> <Icon args id="icon1"></Icon> </div> </>; } hideIcon() { const { icon1 } = this.child; icon1.hide(); // hide() is a custom function in Icon. } hideParent() { // hide() is custom function in parent component. this.parent.hide(); }
-
The
alias
can be used to assign an custom name to the tag.render() { return <> <div> <IconButton args text="home"></IconButton> <icon args text="home" alias={ IconButton }></icon> </div> </>; }
-
The
scope
attribute allows you to control the parent-child relationship between components. By default, when a component is loaded or created within another component, the current component is automatically set as the parent of the newly loaded component. However, there may be scenarios where you want to designate a different parent component. This is where thescope
attribute comes into play.render() { return <> <div> <List args id="list"></List> </div> </>; } add() { const { list } = this.child; // The parent of `Icon` will be current component list.add(<><Icon args></Icon></>); // The parent of `Icon` will be `list` list.add(<><Icon args scope={ list }></Icon></>); }
-
-
-
The events can be assigned to elements in 3 different ways.
-
render() { return <> <div> <button onclick={ this.validate }>Validate</button> </div> </>; } validate() { alert("Validated"); }
-
render() { return <> <div> <button onclick={ () => { alert("Validated"); } }>Validate</button> </div> </>; }
-
main() { this.set("{click}", this.validate); // Or const { click } = this.key; click(this.validate); } render() { return <> <div> <button onclick="{click}">Validate</button> </div> </>; } validate() { alert("Validated"); }
-
-
The values can be assigned to elements in 2 different ways.
-
This type of binding is static and cannot be updated. This have space between curly braces
{}
,{ text }
, if there is no space then it will be considered as a dynamic binding.render() { const text = "Click"; return <> <div> <button>{ text }</button> </div> </>; }
-
This type of binding is dynamic and can be updated. This have no space between curly braces
{}
,{text}
.main() { this.set("{text}", "Click"); // Or const { text } = this.key; text("Click"); } render() { return <> <div> <button>{text}</button> </div> </>; }
-
This type of binding is static and cannot be updated. This have space between curly braces
-
-
id: string
Unique id for component, it can be set while loading component by the tag.example:
const icon = <><Icon args id="icon1"></Icon><>
-
root: Element
The root element of the current component.example:
this.root.classList.add(); this.root.remove();
-
args: any
The values passed while making the component.example:
- While creating component.
const icon = <><Icon args src="home.png"></Icon><>
- Inside the
Icon
's classrender() { return <> <img src={ this.args.src }> </>; }
- While creating component.
-
parent: H12
The parent component of the current component, it will benull
if its root component.example:
console.log(this.parent)
-
child: Object<string, H12>
A collection of child components in the current component.example:
render() { return <> <Icon args id="icon1" src="home.png"></Icon> <Icon args id="icon2" src="link.png"></Icon> </>; } hide1() { this.hideIcon("icon1"); } hide2() { this.hideIcon("icon2"); } hideIcon(id) { this.child[id].hide(); // hide() is custom function in Icon class }
-
element: Object<string, Element>
A collection of unique elements in the current element.example:
render() { return <> <div> <input type="text" id="txtbox" /> </div> </>; } getText() { const { txtbox } = this.element; console.log(txtbox.value); }
-
key: Object<string, Function>
A collection methods to update the key's value, its an alternatively method toset()
.example:
main() { const { name } = this.key; name("Some Name"); // Alternatively this.set("{name}", "Some Name"); } render() { return <> <div> <label>{name}</label> </div> </>; }
-
relay: any
A data that passes from parent component to its child component. If a child component have its own relay then it will merge with parent's relay.example:
class App extends H12 { constructor() { super(); this.relay = { name: "Some Name" }; } render() { return <> <Button args></Button> </>; } } class Button extends H12 { constructor() { super(); } main() { console.log(this.relay.name); // Output: "Some Name" } }
-
render()
The function that returns template that is to be rendered.example:
render() { return <> <div> <button>Click</button> </div> </>; }
-
main(args: any)
The function is called when the component is ready to be rendered. The default values can be set in this function. Theargs
parameter is passed while creating component and is similar tothis.args
.example:
main() { this.set("{link}", "home.png"); this.set("{home}", <><button>Home</button></>); this.set("{icon}", <><Icon args src="icon.png"></Icon></>); const { name } = this.key; name("Some Name"); }
-
set(key: string, value: string | Element | Function)
Theset
method in H12 is used to update or append values in the component's template using a unique key. This method supports various types of values, includingstring
,Element
, andFunction
.The values can also be appended using
++
operator. Note that, if the value type changed, then all the previous values will be cleared and a new value will be appened. For example: If the current value isstring
and anElement
is appended then the previousstring
values will be removed.example:
main() { this.set("{link}", "home.png"); this.set("{home}", <><button>Home</button></>); // add element this.set("{icon}", <><Icon args src="icon.png"></Icon></>); // add component this.set("{char}", "A"); this.set("{char}++", "B"); // appending text this.set("{char}++", "C"); this.set("++{char}", "D"); this.set("{item}", <><li>Item 1</li></>); this.set("{item}++", <><li>Item 2</li></>); // appending element this.set("{click}", () => { console.log("Hello world"); }); // Alternatively you can use `key` method const { item } = this.key; item(<><li>Item 1</li></>); item(<><li>Item 2</li></>, "x++"); } render() { return <> <div> <div>{link}</div> <div>{home}</div> <div>{icon}</div> </div> </>; }
-
destroy()
The function is used to destroy the component and remove it from the DOM and parent.example:
removeChild() { this.child["item"].destroy(); }