{"id":18373047,"url":"https://github.com/reon90/tung","last_synced_at":"2025-04-06T19:32:14.821Z","repository":{"id":57382209,"uuid":"87628795","full_name":"Reon90/tung","owner":"Reon90","description":"A javascript library for rendering html","archived":false,"fork":false,"pushed_at":"2017-08-12T10:11:38.000Z","size":43,"stargazers_count":29,"open_issues_count":0,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-22T05:51:08.703Z","etag":null,"topics":["html","javascript","javascript-library","jsx","react","snabbdom","virtual-dom","vue"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Reon90.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-08T11:22:52.000Z","updated_at":"2024-08-06T20:10:49.000Z","dependencies_parsed_at":"2022-09-26T16:50:14.477Z","dependency_job_id":null,"html_url":"https://github.com/Reon90/tung","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reon90%2Ftung","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reon90%2Ftung/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reon90%2Ftung/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reon90%2Ftung/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Reon90","download_url":"https://codeload.github.com/Reon90/tung/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247539266,"owners_count":20955284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","javascript","javascript-library","jsx","react","snabbdom","virtual-dom","vue"],"created_at":"2024-11-06T00:08:22.701Z","updated_at":"2025-04-06T19:32:13.184Z","avatar_url":"https://github.com/Reon90.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://tungle.ru/public/img/umbrella.png\" alt=\"logo\" height=\"100\"\u003e\n\n# tung\n\nA 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.\n\n## Install\n```\nnpm install tung\n```\n\n**Of course, that you need to convert html to js.**\n```\nnpm install babel-tung\n```\nThere is config for [Webpack](https://webpack.github.io/) and [Gulp](http://gulpjs.com/)\n\n## Features\n\n\u0026bull; based on [snabbdom](https://github.com/snabbdom/snabbdom), a fast and simple virtual DOM library;\n\n\u0026bull; pure html: block defines context, variables, components;\n\n\u0026bull; pure javascript: no jsx, defines only state for rendering html;\n\n\u0026bull; stateful and stateless components;\n\n## Use cases\n\u0026bull; you don't like jsx;\n\n\u0026bull; you have html developers in your team;\n\n\u0026bull; you like [React](https://facebook.github.io/react/) patterns, but you looking for something different;\n\n## Usage\n\n[Demo](https://reon90.github.io/tung/examples/index.html)\n\n```html\n\u003c!-- page.tpl --\u003e\n\u003cdiv\u003e\n    \u003cdiv class=\"users\"\u003e\n        \u003cCard block=\"users\" /\u003e\n    \u003c/div\u003e\n    \u003cBtn block=\"btn\" /\u003e\n\u003c/div\u003e\n\n\u003c!-- btn.tpl --\u003e\n\u003cspan class=\"btn\"\u003e{this.text}\u003c/span\u003e\n\n\u003c!-- card.tpl --\u003e\n\u003cdiv class=\"item item--admin\"\u003e\n    \u003cimg src={this.img} width=\"50\" height=\"50\" /\u003e\n    \u003cspan class=\"item__content\"\u003e{this.name}\u003cspan block=\"isAdmin\"\u003e \u0026bull; admin\u003c/span\u003e\u003c/span\u003e\n    \u003cBtn block=\"btn\"/\u003e\n    \u003cBtn block=\"delete\"/\u003e\n\u003c/div\u003e\n```\n\n```js\nimport {Tung} from 'tung';\nimport card from './card';\nimport page from './tpl/page';\nimport btn from './tpl/components/btn';\n\nclass Users extends Tung {\n    constructor(container) {\n        super(container);\n\n        this.setView(page, btn, card); // IMPORTANT\n        \n        fetch('https://api.github.com/users/octocat/following')\n            .then(response =\u003e response.json())\n            .then(users =\u003e this.ready(users))\n            .catch(console.error);\n    }\n\n    ready(users) {\n        users[Symbol.iterator] = this.getUsers;\n        this.usersIterator = users[Symbol.iterator]();\n\n        this.setState({ // IMPORTANT\n            users: [this.buildUser(this.usersIterator.next().value)],\n            btn: {\n                text: 'Load more',\n                on: { click: this.handleEvent }\n            }\n        });\n    }\n    \n    buildUser(user) {\n        return {\n            name: user.login,\n            img: user.avatar_url,\n            url: user.html_url,\n            isAdmin: user.site_admin,\n            id: user.id,\n            onDeleteProfile: [this.onDeleteProfile, this]\n        };\n    }\n    \n    handleEvent(e) {\n        let user = this.usersIterator.next();\n        if (user.done) {\n            delete this.state.btn;\n        }\n        this.state.users.push(this.buildUser(user.value));\n        this.setState(this.state); // IMPORTANT\n    }\n    \n    onDeleteProfile(e) {\n        let index = this.state.users.findIndex(user =\u003e user.id === e.target.data.id);\n        this.state.users.splice(index, 1);\n        this.setState(this.state); // IMPORTANT\n    }\n\n    * getUsers() {\n        for (let i = 0; i \u003c this.length; i++) {\n            if (this.length === i + 1) {\n                return this[i];\n            } else {\n                yield this[i];\n            }\n        }\n    }\n}\n\nnew Users(root);\n```\n\n## API\n\n### methods\n| name      | argument | description                               |\n|-----------|----------|-------------------------------------------|\n| setView   | function | Defines which components will use         |\n| setState  | object   | Render html from object                   |\n### hooks (not called for root)\n| name      | argument | description                               |\n|-----------|----------|-------------------------------------------|\n| init      | null     | Called when component was created         |\n| destroy   | null     | Called when component was removed         |\n### props\n| name      | type     | description                               |\n|-----------|----------|-------------------------------------------|\n| refs      | object   | Stores stateful children components       |\n| els       | object   | Stores DOM elements                       |\n### html syntax\n| name      | type     | description                               |\n|-----------|----------|-------------------------------------------|\n| block     | attribute| Name of context                           |\n| Component | tag      | Name of component                         |\n| this      | object   | Access to context                         |\n### state properties\n| name      | type     | description                               |\n|-----------|----------|-------------------------------------------|\n| on        | object   | ```{ on: { click: this.onClick } }```     |\n| attrs     | object   | ```{ attrs: { placeholder: 'Text' } }```  |\n| props     | object   | ```{ props: { data: { id: 12345 } } }```  |\n| class     | object   | ```{ class: { toggle: true } }```         |\n| style     | object   | ```{ style: { display: 'none' } }```      |\n\n**Feel free to offer new features 🤔**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freon90%2Ftung","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freon90%2Ftung","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freon90%2Ftung/lists"}