hta
v1.3.1
Published
The tiny framework for building Hyper Text Application with ease
Downloads
23
Maintainers
Readme
HTA
The tiny framework for building Hyper Text Application with ease
Why HTA ?
- Write less do more
- No compiler or bundler needed
- Easy to convert HTML template to HTA
- Extremely fast DOM updating
- Built-in store and router
Installation
npm install hta --save
Comparison with Other Frameworks
Syntax
Let's create simple counter app
HTA
import { $, render } from "hta";
const initialState = { count: 0 };
const Increase = ({ count }) => ({ count: count + 1 });
const CounterValue = (props, select) => $`<h1>${select("count")}</h1>`;
const CounterAction = () =>
$`<button ${{ onclick: [Increase] }}>Increase</button>`;
const App = () => $`
${CounterValue}
${CounterAction}`;
render(App, { state: initialState });
React + Redux Toolkit
import React from "react";
import { render } from "react-dom";
import { connect, Provider } from "react-redux";
import { configureStore, createAction, createReducer } from "@reduxjs/toolkit";
const increment = createAction("INCREMENT");
const reducer = createReducer(0, {
[increment.type]: (state) => state + 1,
});
const store = configureStore({ reducer });
const CounterValue = connect((state) => ({ count: state }))(({ count }) => (
<h1>{count}</h1>
));
const CounterAction = connect(null, { increment })(({ increment }) => (
<button onClick={increment}>Increase</button>
));
const App = () => (
<>
<Provider store={store}>
<CounterValue />
<CounterAction />
</Provider>
</>
);
render(<App />, document.body);
Features
| Feature | HTA | React | Vue | Angular | | :------------------------ | :-----: | :-----: | :-----: | :-----: | | Compiler / Bundler needed | | ☑ | ☑ | ☑ | | Async Rendering | ☑ | | | | | Two Way Binding | ☑ | | ☑ | ☑ | | SVG Supported | ☑ | | ☑ | ☑ | | Directive | ☑ | | ☑ | ☑ | | Built-in Router | ☑ | | | ☑ | | Built-in Store | ☑ | | | | | Suspense | ☑ | ☑ | | | | Declarative | ☑ | ☑ | | | | Component | ☑ | ☑ | ☑ | ☑ | | Functional Hooks | ☑ | ☑ | ☑ | | | Lazy Component | ☑ | ☑ | ☑ | ☑ | | Shared Context | ☑ | ☑ | ☑ | ☑ |
Basic Usages
Render simple HTML
import { $, render } from "hta";
render($`<h1>Hello World</h1>`);
Using substitutions
import { $, render } from "hta";
render($`<h1>It is ${new Date().toLocaleTimeString()}.</h1>`);
If the substitution is:
- string/number/Date: It will be rendered as text node
- boolean/undefined/null: It will not be rendered
- Function: HTA understands the function is component and render the component content/result
- Tuple [Function, object]: HTA renders component with specified props (the second item of tuple)
- Promise/Plain object: By default HTA renders these text node, and the node value is toString() result, but you can add extras (please refer JSON tag extras) to handle plain object rendering.
Using element binding
import { $, render } from "hta";
render(
// add style attribute and textContent property bindings to DIV element
$`<div ${{ style: "font-weight: bold", textContent: "Hello World" }}></div>`
);
The binding must be placed in open tag. You can bind any element property / attribute.
Handling element event
import { $, render } from "hta";
render($`<button ${{ onclick: () => alert("Hello World") }}>Click me</button>`);
HTA treats the binding which starts with on*** as event handler.
If you want to bind some element property/attribute which starts with on*** ? Using { attr: { attrName: value } } for attribute binding and { prop: { propName: value } } for property binding
Updating element text
There are 2 ways to update element text
- Using text / textContent binding
- Using substitution is more flexible than above
import { $, render } from "hta";
render($`
<button ${{ text: "Button 1" }}></button>
<button ${{ textContext: "Button 2" }}></button>
<button>${"Button 3"} ${"Other text"}</button>
`);
Updating element HTML
There are 2 ways to update element HTML
- Using text / textContent binding
- Using substitution is more flexible than above
import { $, render } from "hta";
render($`
<button ${{ html: "<strong>Button 1</strong>" }}></button>
<button ${{ innerHTML: "<strong>Button 2</strong>" }}></button>
<button>${$`<strong>Button 3</strong>`} ${$("Other HTML")}</button>
`);
Component
HTA component is pure function, that receives component props and return component content
function MyComponent(props) {
return $`<h2>Hello ${props.name}</h2>`;
}
function App() {
return $`
<h1>Component Demo</h1>
<!-- passing tuple to substitution to render MyComponent with specified props -->
${[MyComponent, { name: "World" }]}
`;
}
render(App);
Component content is anything, it is the same as substitution
Advanced Usages
Examples
- Todo MVC(140 lines of code)
- Todo App (4000 todos)
- Crypto Search (5600 coins)
- Silky Smooth (Fast enough to render over 500 elements at 60fps)
- Performance testing
- SVG Animation
- (more examples)[https://github.com/linq2js/hta/tree/master/examples]