A javascript library for rendering html. Tung helps to divide html and javascript development. In order to start working with tung, you only need to know two methods, setView and setState.
npm install tung
Of course, that you need to convert html to js.
npm install babel-tung
There is config for Webpack and Gulp
• based on snabbdom, a fast and simple virtual DOM library;
• pure html: block defines context, variables, components;
• pure javascript: no jsx, defines only state for rendering html;
• stateful and stateless components;
• you don't like jsx;
• you have html developers in your team;
• you like React patterns, but you looking for something different;
<!-- page.tpl -->
<div>
<div class="users">
<Card block="users" />
</div>
<Btn block="btn" />
</div>
<!-- btn.tpl -->
<span class="btn">{this.text}</span>
<!-- card.tpl -->
<div class="item item--admin">
<img src={this.img} width="50" height="50" />
<span class="item__content">{this.name}<span block="isAdmin"> • admin</span></span>
<Btn block="btn"/>
<Btn block="delete"/>
</div>
import {Tung} from 'tung';
import card from './card';
import page from './tpl/page';
import btn from './tpl/components/btn';
class Users extends Tung {
constructor(container) {
super(container);
this.setView(page, btn, card); // IMPORTANT
fetch('https://api.github.com/users/octocat/following')
.then(response => response.json())
.then(users => this.ready(users))
.catch(console.error);
}
ready(users) {
users[Symbol.iterator] = this.getUsers;
this.usersIterator = users[Symbol.iterator]();
this.setState({ // IMPORTANT
users: [this.buildUser(this.usersIterator.next().value)],
btn: {
text: 'Load more',
on: { click: this.handleEvent }
}
});
}
buildUser(user) {
return {
name: user.login,
img: user.avatar_url,
url: user.html_url,
isAdmin: user.site_admin,
id: user.id,
onDeleteProfile: [this.onDeleteProfile, this]
};
}
handleEvent(e) {
let user = this.usersIterator.next();
if (user.done) {
delete this.state.btn;
}
this.state.users.push(this.buildUser(user.value));
this.setState(this.state); // IMPORTANT
}
onDeleteProfile(e) {
let index = this.state.users.findIndex(user => user.id === e.target.data.id);
this.state.users.splice(index, 1);
this.setState(this.state); // IMPORTANT
}
* getUsers() {
for (let i = 0; i < this.length; i++) {
if (this.length === i + 1) {
return this[i];
} else {
yield this[i];
}
}
}
}
new Users(root);
name | argument | description |
---|---|---|
setView | function | Defines which components will use |
setState | object | Render html from object |
name | argument | description |
---|---|---|
init | null | Called when component was created |
destroy | null | Called when component was removed |
name | type | description |
---|---|---|
refs | object | Stores stateful children components |
els | object | Stores DOM elements |
name | type | description |
---|---|---|
block | attribute | Name of context |
Component | tag | Name of component |
this | object | Access to context |
name | type | description |
---|---|---|
on | object | { on: { click: this.onClick } } |
attrs | object | { attrs: { placeholder: 'Text' } } |
props | object | { props: { data: { id: 12345 } } } |
class | object | { class: { toggle: true } } |
style | object | { style: { display: 'none' } } |
Feel free to offer new features 🤔