vanu
v0.2.0
Published
Lightweight library for creating UI without build tools.
Downloads
33
Readme
Vanu
Lightweight library for creating UI without build tools.
Demo SSR => https://vanilla-ssr-gilt.vercel.app
status => under development.
Features
- Just ~2kb gzipped, ~5kb minified.
- No build tools.
- Router support.
- Middleware support.
- LazyLoad js support.
- Listener
before
andafter
load.
Install
npm or yarn
npm i vanu
// or
yarn add vanu
Browser
<!-- non module -->
<script src="//unpkg.com/vanu"></script>
<!-- es module -->
<script type="module">
import vanu from "https://unpkg.com/vanu/dist/index.esm.js";
const app = vanu();
//other code
</script>
Usage
<html>
<head>
<!-- add vanu -->
<script src="//unpkg.com/vanu"></script>
</head>
<body>
<!-- target id app -->
<div id="app"></div>
<!-- your js -->
<script>
const { useValue, render, html, toAction } = vanu({ target: "#app" });
const count = useValue(0);
const myClick = () => count.value++;
render(() => html`
<button onclick="${toAction(myClick)}">click !</button>
<h2>Counter: ${count.value}</h2>
`)
</script>
</body>
</html>
Extension vscode for literal html lit-html
For custom element as WebComponent web-component
Router
...
<nav>
<a href="#/" u-link>Home</a>
<a href="#/about" u-link>About</a>
</nav>
<div id="app"></div>
<script>
const app = vanu({ target: "#app" });
app.get("/", ({ render, html, useValue }) => {
render(() => html`
<h1>Welcome Home</h1>
`)
});
app.get("/about", ({ render, html, useValue }) => {
render(() => html`
<h1>Welcome About</h1>
`)
});
// listen router
app.listen();
</script>
...
The router is a app.get(path, (context) => {...})
Context
context is a single object for render, html, useValue, params, query and more.
useValue
...
const text = useValue();
const onChangeText = (e) => {
text.value = e.target.value;
}
render(() => html`
<input value="${text.value}" oninput="${toAction(onChangeText)}" />
`)
...
toAction
Simple wrapper function to string in global window/url.
toAction(fn: Function, key?: string)
.
The key is required when function without name.
...
render(() => html`
<button onclick="${toAction(() => {...})}">Click !!</button>
`)
...
Params And Query
const app = vanu({ target: "#app" });
// example query => /user?name=vanu
app.get("/user", ({ render, html, query }) => {
render(() => html`
<h1>Welcome name ${query.name}</h1>
`)
});
// example params => /user/123
app.get("/user/:id", ({ render, html, params }) => {
render(() => html`
<h1>Welcome id ${params.id}</h1>
`)
});
app.listen();
Watch useValue
watch value
...
const text = useValue('', (value) => {
if (value === 'hello') {
alert(value + ' world');
}
});
const onChangeText = (e) => {
text.value = e.target.value;
}
render(() => html`
<input value="${text.value}" oninput="${toAction(onChangeText)}" />
`)
...
Router Without Hash
...
<nav>
<a href="/" u-link>Home</a>
<a href="/about" u-link>About</a>
</nav>
<div id="app"></div>
<script>
const app = vanu({ target: "#app" });
app.get("/", (ctx) => {...});
app.get("/about", (ctx) => {...});
app.listen();
</script>
...
Default Route
...
<nav>
<a href="#/home" u-link>Home</a>
<a href="#/about" u-link>About</a>
</nav>
<div id="app"></div>
<script>
const app = vanu({ target: "#app" });
app.get("/", (ctx) => {
window.location.href = '#/home';
// now home is default route
});
app.get("/home", (ctx) => {...});
app.get("/about", (ctx) => {...});
app.listen();
</script>
...
Lazy Load
...
const app = vanu({ target: "#app" });
app.get("/", (ctx) => ctx.lazy("./path/to/home.js"));
app.listen();
...
...
// /path/to/home.js
function home(ctx) {...}
...
With Base Href (for XAMPP or laragon or electron)
...
<html>
<head>
<!-- add base href before vanu -->
<base href="/myapp">
<script src="//unpkg.com/vanu"></script>
</head>
<body>
...
</body>
</html>
...
Middleware
function fooMidd(ctx, next) {
ctx.foo = "foo";
next();
};
function barMidd(ctx, next) {
ctx.bar = "bar";
next();
};
const app = vanu({ target: "#app" });
app.use(fooMidd);
app.get("/", barMidd, ({ render, html, foo, bar }) => {
render(() => html`<h1>${foo + bar}</h1>`);
});
app.listen();
Listener like start, end and error
...
//on page start
app.on("vanu:start", (event) => {
console.log("Start");
});
//on page end
app.on("vanu:end", (event) => {
console.log("End");
});
//on handle error
app.on("vanu:error", (error, { render, html }) => {
console.log(error.message);
render(() => html`<h1>${error.message || "Something went wrong"}</h1>`);
});
...
Config
const app = vanu({
//parseQuery
parse?: (str: string) => Record<string, any>,
//base url
base?: string,
//timeout for load page vanu:start and vanu:end default 300.
timeout?: number
});