Jetz is a front-end framework javascript for build a front end with declarative javascript DOM.
Write this command in terminal :
npm install
npm run watch
npm run start
Jetz is inspired by Jetpack Compose. Is using for creating rich UI with simple, fast, declarative syntax in android. But Jetz was coming for Web Developers.
- element function
- element function
- composable variable
- conditional element
- state management
- routing
Empty body element in index.html
<body></body>import { Jetz } from "./src/jetz/jetz";
import { find } from "./src/jetz/jetz-ui";
let App = div('Hello World');
Jetz.mount(App, document.body);Thinking in Jetz in html :
<div class="container">
<ul class="todo-list">
<li>Item 1 </li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>in javascript with Jetz :
const item = [1, 2, 3];
const todo =
div( css`container`,
ul( css`todo-list`,
items.map(data => li('Item ' + data))
)
);in html :
<button class="btn btn-info" type="button" onclick="showAlert('Aww Snap')">
Show Alert
</button>
....
<script>
function showAlert(text){
alert(text);
}
</script>in javascript with Jetz :
button('Show Alert', css`btn btn-info`, {
onclick(){
alert('Aww Snap');
}
});in html :
<p id="my-content">This is paragraph of your content</p>
<button type="button" onclick="changeText()"></button>
...
<script>
let myContent = document.getElementById('my-content');
function changeText(){
myContent.innerText = 'Paragraph was changed into other content';
}
</script>in javascript with Jetz :
let myContent = p('This is paragraph of your content');
button({
onclick(){
myContent.text('Paragraph was changed into other content');
}
});You can define a Component with three ways, with Component class, Function, or Variable :
With variable :
let MovieApp = div( css`container`,
div( css`row`,
div( css`col-md-3`,
ul( css`navbar`,
li( css`navbar-item`, 'MENU 1'),
li( css`navbar-item`, 'MENU 1'),
li( css`navbar-item`, 'MENU 1')
)
),
div( css`col-md-9`,
// ...
),
// ...
)
// ...
);
export default MovieApp;Or with Function :
function MovieApp(){
return div( css`container`,
div( css`row`,
//...
),
//...
)
}
export default MovieApp;Or with Component class, it's need a render method to render an element :
class MovieApp extends Component {
showMessage(message){
alert(message);
}
render(){
return (
div( css`movie-body`,
button( css`btn btn-info`, 'Show Message', {
onclick:() => {
this.showMessage('Hello World');
}
})
//...
)
)
}
}
export default MovieApp;You can passing data as argument of class or argument function it self, example :
With function
let PostCard = function(title, content){
return div( css`card`,
div( css`card-title`, title),
div( css`card-body`,
p(content)
)
)
}
// Sample with data
let userPosts = [
{ title: 'Black Bird', message: 'A bird with black color'},
{ title: 'Red Bird', message: 'A bird with red color'},
{ title: 'Green Bird', message: 'A bird with green color'},
];
// Call a function in element child
let RootPage = div( css`container`,
div( css`row`,
div( css`col-12`,
loop( userPosts, post => PostCard(post.title, post.message))
)
)
)Passing data in Component
class MyButton extends Component{
say = '';
word = '';
constructor(say, word){
super();
this.say = say;
this.word = word;
}
showMessage(){
alert(`${this.say} ${this.word}`);
}
render(){
return (
button('Show Message', {
onclick:() => this.showMessage()
})
)
}
}
// sample instance variable
let _mybutton = new MyButton('Hello', 'World');
// Call Component in element
let RootPage = main( css`container`,
// with new instance
new MyButton('Hello', 'World'),
// OR with new function
MyButton.new('Hello', 'World'),
// Or with instance variable
_mybutton
);Create an event listener in element.
let myCounter = function(){
let counter = stateOf(0);
return button('Count : ', counter, {
onclick(){
counter.value++;
}
})
};
export default myCounter;Or
let counter = stateOf(0);
let myCounter = button('Count : ', counter, {
onclick(){
counter.value++;
}
});
export default myCounter;Or
let counter = stateOf(0);
let myCounter = button('Count : ', counter)
.on('click', e => { counter.value++; });Or in Component class
Note : if you want to use `this` as Component it self, you must write listener with arrow function
export class MyCounter {
counter = stateOf(0);
render(){
return button('Counter', this.counter, {
onclick:() => {
this.counter.value++;
}
})
}
}find(selector) // is used for get one element by selector and returned HTMLElement
findAll(selector):Array<HTMLElement> // is used for get some element by selectorexample :
let MainApp = main(
button('Click ME', {
onclick(){
find('#my-label').innerText = 'Clicked';
// OR use $ to call instance of JetzElement
// find('#my-label').$.text('Clicked');
}
}),
label(id`my-label`, 'You are not yet clicked')
)Jetz was have a state built-in, which is stateOf and listOf and sequenceOf
stateOf function is used for single value it could be string, numeric, object, or element.
examplelet counter = stateOf(0);
let myButton = button('Clicked ', counter, {
onclick(){
counter.value++;
}
})listOf function is used for array/collections of value it could be string, numeric, object, or element.
examplelet myStack = listOf();
let myButton = button('Clicked ', {
onclick(){
myStack.push('New Item');
}
})sequenceOf function is used for unique string or number, that may be same value, but element is different
examplelet myStack = sequenceOf();
let MyApp = main(
ul(
loop( myStack , stack => (
li(stack, button('delete', {
onclick() {
myStack.remove(stack)
}
})
)
),
button('Clicked ', {
onclick(){
myStack.push('New Item');
}
})
)Example state list :
let cartState = listOf();
let myApp = main(
ul(
loop(cartState, item => li(item))
),
button('Add new item', {
onclick() {
cartState.push(`New Item ${cartState.length + 1}`)
}
})
);Jetz with state and binding value :
let myState = stateOf('');
let myComponent = div(
div('My name is : ', myState),
inputText({
bind: myState,
placeholder: 'Input your name...'
})
);For conditional element Jetz using function with callback parameter that return boolean to recheck condition, because that element will revalidated when the value was changed.
use _if(() => condition) example :
div( _if(() => 1 > 3),
'content'
) // it will hidden, because value is falseuse _elseif(() => condition) example :
let counter = stateOf(0);
let myComponent = div(
div( if(() => counter.value == 1),
'One'
),
div( _elseif(() => counter.value == 2),
'Two'
),
button( 'count',{
onclick(){
counter.value++;
}
})
)use _else property example :
let isShow = stateOf(true);
let myComponent = div(
div( if(() => isShow.value),
'Im true'
),
div( _else,
'Im false'
),
button('Change value', {
onclick(){
isShow.value = false;
}
})
)Or with _if, _elseif, and _else
let counter = stateOf(0);
let myComponent = div(
div('Number is : ',
div( _if(() => counter.value == 0),
'Zero'
),
div( _elseif(() => counter.value == 1),
'One'
),
div( _elseif(() => counter.value == 2),
'Two'
),
div( _else,
'More (', counter,')'
),
),
button('Count', {
onclick(){ counter.value++ }
})
);let pageContent = stateOf(div())
let dispatcher = new Dispatcher(action => {
if(action === 'home'){
pageContent.value = home()
}else if(action === 'about'){
pageContent.value = about()
}else if(action === 'contact-us'){
pageContent.value = contactUs()
}
})
let myApp = main(
nav(
ul(
li('Home').on('click', () => dispatcher.dispatch('home')),
li('About').on('click', () => dispatcher.dispatch('about')),
li('Contact Us').on('click', () => dispatcher.dispatch('contact-us'))
)
),
pageContent
)Register route into Jetz
import { Jetz } from "./src/lib/jetz";
import { Router, route } from "./src/lib/jetz-router";
import { MovieApp } from './src/components/movie-app/movie-app';
import { MovieHome } from "./src/components/movie-app/movie-home";
import { MovieSeries } from "./src/components/movie-app/movie-series";
let router = new Router(
route('/', MovieHome),
route('series', MovieSeries)
);
// register router in Jetz
Jetz.use(router);
// mount compose element into document.body
Jetz.mount(MovieApp, document.body);Place routeBrowser and link in element
function menuBar(){
return ul( css`menu-list`,
link('/',
li( css`menu-item`, 'Home')
),
link('series',
li( css`menu-item`, 'Series')
),
)
}
let MovieApp = function(){
return main(
menuBar,
Jetz.$route.browser()
)
}
export default MovieApp;If this repository get 100 stars i'll focus to develop this library more intens. ☕
Author @daevsoft
