@ledge/jsx
Simple JSX implementation for working directly with HTML elements. Types included.
Features
- Full Custom Elements support
- Full TypeScript support
- Tiny footprint
- Zero runtime dependencies
- Zero virtualization overhead
Usage
import { h } from '@ledge/jsx';
let clickCounter = 0;
const jsxButton = <button id='native-onlick' class='btn btn-dark my-4'
onclick={() => console.info(`Clicked ${++clickCounter} times`)}>
Click Me
</button>;
jsxButton.click(); // "Clicked 1 times"
jsxButton.click(); // "Clicked 2 times"
class CustomElementExample extends HTMLElement {
connectedCallback() {
this.classList.add('lead');
}
}
customElements.define('custom-element-example', CustomElementExample);
const jsxSection =
<section class='card'>
<h2>DOM in JSX</h2>
<h3>Work directly with DOM elements using JSX's declarative syntax</h3>
<custom-element-example>Custom Elements?</custom-element-example>
<br />
<CustomElementExample>Fully Supported!</CustomElementExample>
<br />
{jsxButton}
</section>;
document.body.appendChild(jsxSection);
jsxSection.parentElement === document.body; // true
jsxButton.closest('.card') === jsxSection; // true
TypeScript
The following configuration is required:
{
"compilerOptions": {
"lib": ["dom"],
"jsx": "react",
"jsxFactory": "h"
}
}
By default, the assigned type will be HTMLElement
. If you need the subtype, cast the expression:
const tpl = <template>{/** ... */}</template> as HTMLTemplateElement;
const tplClone = tpl.content.cloneNode(true); // ok
A global CustomElement
interface is provided for working with Custom Elements:
// error without extending HTMLElement
class CustomElementExample extends HTMLElement implements CustomElement {
// autocompletion & documentation for callbacks
public connectedCallback() {
// ...
}
// error on mistyped parameter
public attributeChangedCallback(name: string) {
// ...
}
}