{"id":13657025,"url":"https://github.com/danielmascena/calque","last_synced_at":"2025-04-12T02:24:50.754Z","repository":{"id":34135811,"uuid":"158863215","full_name":"danielmascena/calque","owner":"danielmascena","description":"📑 Bringing the power and functionality of JavaScript, but with the readability of HTML.","archived":false,"fork":false,"pushed_at":"2023-01-03T17:03:03.000Z","size":9287,"stargazers_count":65,"open_issues_count":12,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-12T02:24:41.537Z","etag":null,"topics":["html","javascript","javascript-library","micro-library","usetheplatform","webcomponents"],"latest_commit_sha":null,"homepage":"","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/danielmascena.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":"2018-11-23T17:51:26.000Z","updated_at":"2023-04-02T11:24:29.000Z","dependencies_parsed_at":"2023-01-15T04:49:41.575Z","dependency_job_id":null,"html_url":"https://github.com/danielmascena/calque","commit_stats":null,"previous_names":["danielmascena/constrict","danielmascena/engraft","danielmascena/label.js","danielmascena/piquant","danielmascena/stampify","danielmascena/strato"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielmascena%2Fcalque","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielmascena%2Fcalque/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielmascena%2Fcalque/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielmascena%2Fcalque/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielmascena","download_url":"https://codeload.github.com/danielmascena/calque/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248506310,"owners_count":21115416,"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","micro-library","usetheplatform","webcomponents"],"created_at":"2024-08-02T05:00:35.986Z","updated_at":"2025-04-12T02:24:50.734Z","avatar_url":"https://github.com/danielmascena.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"[![calque.png](https://i.postimg.cc/BbrSv6qm/calque.png)](https://postimg.cc/K35Sqm3T)\n\n\n# CalqueJS 📑\n* Zero dependencies\n* Framework-free\n* No transpilation needed\n\\o/ [#usetheplatform](https://webplatform.github.io/) \n\n![downloads-badge](https://flat.badgen.net/npm/dt/calque)\n![version-badge](https://flat.badgen.net/npm/v/calque)\n![license-badge](https://flat.badgen.net/npm/license/calque)\n\n\u003e ## 🛠 Status: In Development 🚧\n\nCalque is a tiny helper library (_only ~7KB_) for the native web platform, aimed to help to build interfaces easily. The goal is to offer a declarative way to code UI components by writing bits of [HTML](https://html.spec.whatwg.org/multipage/), rather the traditional client-side scripting, and also providing a simple layer as Virtual DOM to update the view 🖼️ changes.\n\nIt is all based on Web Standards, 💪powered by [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) language, [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) \u0026 [browser](https://developer.mozilla.org/en-US/docs/Web/API/Window) APIs. The library calques, or transcript, the HTML-like template inner data translating into the respective properties on the target [ELEMENT_NODE](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) type object. This approach aims to aid coding [Web Components](https://www.webcomponents.org/) 🖤💙💛, especially as an add-on for **Custom Elements** (which are awesome). They play a key role at [micro frontends](https://micro-frontends.org) and make possible to reuse code on web platform.\n\n\n\n## Install via:\n\n[NPM](https://npmjs.com) (Terminal)\n```sh\n$ npm install --save calque\n```\n\n\n## Build components with a light abstraction\n\n### Custom Elements v1 using ES6\n\n\n```javascript\nimport { innerHTML, html } from '../dist/calque.mjs';\n\nwindow.customElements.define('my-component', class extends HTMLElement {\n  static get observedAttributes() { return ['name', 'data-list'];}\n  constructor(...args) {\n    super(...args);\n    this.showNodeName = this.showNodeName.bind(this);\n  }\n  attributeChangedCallback() { this.render(); }\n  connectedCallback() { this.render(); }\n  showNodeName() {\n    alert(this.nodeName);\n    this.setAttribute('name', 'Neo name');\n  }\n  render() {\n    const colorProp = 'color';\n    const name = this.getAttribute('name');\n    this[innerHTML] = html`\n      \u003cp onblur=\"${(e)=\u003econsole.log(e.target.textContent)}\" \n        contenteditable\u003e\n        Temporary text\n      \u003c/p\u003e\n      \u003ch3 onclick=\"${this.showNodeName}\" \n        style=\"${{[colorProp]: \"red\",\"font-size\": name.length+\"em\"}}\"\u003e\n        Hello, \u0026lambda; ${name}\n      \u003c/h3\u003e\n      \u003caside\u003e\n        \u003cul\u003e${this.hasAttribute('data-list') \n          \u0026\u0026 this.getAttribute('data-list').split(',').map(num =\u003e html`\u003cli\u003e${num}\u003c/li\u003e`)}\u003c/ul\u003e\n        \u003cbutton onclick=\"${(function removeItem() {\n            if (this.hasAttribute('data-list')) {\n              let list = this.getAttribute('data-list');\n              let lastIndex = list.lastIndexOf(',');\n              this.setAttribute('data-list', list.slice(0, lastIndex));\n            } else {\n              console.warn('No data-list attribute found');\n            }\n          }).bind(this)}\"\u003e-\u003c/button\u003e\n      \u003c/aside\u003e\n    `;\n  }\n});\n```\n\n\n### Or for Web Component using ES5\n\n```js\nimport {innerHTML, html} from '../calque.mjs';\n\nfunction NeoTag() {\n\tconsole.log(this.constructor);\n\tthis.count = 0;\n\treturn Reflect.construct(HTMLElement, [], this.constructor);\n}\nNeoTag.prototype = Object.create(HTMLElement.prototype);\nNeoTag.prototype.constructor = NeoTag;\nObject.setPrototypeOf(NeoTag, HTMLElement);\nNeoTag.prototype.handlerClick = function click(){console.log('clicked', this);};\nNeoTag.prototype.connectedCallback = function() {\n\tthis[innerHTML] = html`\u003cp onclick=\"${this.handlerClick.bind(this)}\"\u003eNeo Tag\u003c/p\u003e`;\n};\ncustomElements.define('neo-tag', NeoTag);\ndocument.body.appendChild(document.createElement('neo-tag'));\n```\n\n### A delightful VDOM-like approach\n\nCalque updates the DOM nodes after the changes on component attributes to reflect the new values.\n\n![ogImage](https://i.postimg.cc/vBHVjpv6/calquejs-video.gif)\n\n[Live Demo](https://next.plnkr.co/edit/XTq7fqxyQawTeQuwdsZi?preview)\n\n\n⚠️ **Warning**: The component built using Calque it's intended to be concise and reflect the template content, with that said, the component DOM tree shouldn't be modified via DOM API (removing or adding new nodes).\n\n\n## Features\n\n🔧The motivation for this library comes basically inspired for what [JSX](https://reactjs.org/docs/introducing-jsx.html) represents for [React](https://reactjs.org/), I must say that it's too boring to use React without JSX, because it simplifies the coding of a React component using a common HTML grammar.\n\nWith the advent of Web Components, it's now possible to achieve some features provide by frameworks and libraries, but using the timeless advantage of the native web. The component pattern is one of the major benefits of reusable Web Components, which enables to break the UI into distinct and small chunks of code providing a modular and reusable component to be used in many different contexts.\n\n\u003eWeb Components use a set of standardized APIs that are natively supported in all modern browsers. These UI components run on nearly all mobile devices and desktop browsers today.\n\n### Simplify web interface implementation.\n\nNothing new or needed to learn, the mantra is 🙏 - _no third-party libraries/frameworks APIs to interact, just some conveniences_. **Using Calque is as easy as using template tags**. This feature was added at [EcmaScript](https://www.ecma-international.org/memento/tc39.htm) [2015 (6)](https://www.ecma-international.org/ecma-262/6.0/) as Template literals, which are simply functions that allow creating domain-specific languages (DSLs). For more details about The [HTML templating](http://exploringjs.com/es6/ch_template-literals.html#sec_html-tag-function-implementation), access the book _ExploringJS_ by Dr. Axel Rauschmayer.\n\n\u003e Just for curiosity, 🤔 _In linguistics, a [calque](https://en.wikipedia.org/wiki/Calque) /kælk/ or loan-translation is a borrowing of a compound word from another language where each component is translated into native words and then joined together_. \n\nThis definition sums up the idea behind Calque, it intends to maximize the readability using the web markup _lingua franca_, at the same time, it enhances the component by bootstrapping his content and avoids some mandatory JS-DOM boilerplate codes.\n\n\n### Some subtle differences and gotchas\n\nWhen using the library, pay attention to this details mentioned below:\n\n1. Adding Event Listeners smoothly: use function reference `onevent=\"myFunction\"`, not function invocation `onevent=\"myFunction()\"`. Note that in HTML, event listener names are written only in lowercase, such as onclick, onmouseover, etc. In some libraries, however, like JSX or lit-html, event listener names are written in camelCase or with the prefix @, such as onClick or @click, respectively. The philosophy behind Calque is to avoid at the most any divergence from common HTML syntax.\n2. Passing inline CSS properties not only through strings but by literal objects too: when using styling objects, the [JSON](https://www.json.org/)-based format is mandatory. for example, you can pass a JSON object for the style attribute as`{[myProp]: \"7px\", \"border-color\": myValue}`. **OBS:** single properties names will work `{color: \"blue\"}` but are better to follow the standard rules.\n3. Avoid use the **innerHTML** property directly. In JavaScript, you can use a variable value to access the respective property name (`var f='foo',o={foo:'bar'}; o[f] // outputs \"bar\"`), so instead of use `document.body.innerHTML` or `document.body[\"innerHTML\"]`, you **must** import and use the `innerHTML` variable from CalqueJS, and them call `document.body[innerHTML]` together with the  `html` tagged template function provided (_html_ method is primarily a convenience function, and it can be especially useful when manipulating callback events).\n4. Follow the [best practices](https://google.github.io/styleguide/htmlcssguide.html#HTML_Quotation_Marks), we use double quotes for attributes values.\n\n\n#### Code Example\n\nUse [Serve](https://github.com/zeit/serve) as recommended Web Server, run:\n\n```sh\n$ npm i serve\n```\n\n### Roadmap 🎯\nThere are quite a few things to be done:\n- Attributes (not observed) updating\n- Apply some code refactors (more functional programming style)\n- Investigating Shadow DOM support\n\n---\n\n## License\n\nCode licensed under the [MIT License](LICENSE).\n\n---\n\n☑️ Suitable for web UI prototyping 👌\n\n☢️ **use at your own risk** ☣️\n\n🏁 If you considering to use Calque, feel free to share your feedback, thanks a lot 😁\n\n### Some cool resources\n\n\nhttps://github.com/w3c/webcomponents/\n\nhttps://developers.google.com/web/fundamentals/web-components/customelements\n\nhttps://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements\n\nhttps://blog.usejournal.com/web-components-will-replace-your-frontend-framework-3b17a580831c\n\nhttps://www.youtube.com/watch?v=dTW7eJsIHDg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielmascena%2Fcalque","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielmascena%2Fcalque","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielmascena%2Fcalque/lists"}