0.2.0 • Published 2 years ago

vanu v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Vanu

npm version License download-url

Lightweight library for creating UI without build tools.

See examples

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 and after 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>`);
});
...

See example with ssr

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
});

License

MIT

0.2.0

2 years ago

0.1.8

2 years ago

0.1.7

2 years ago

0.1.9

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.0

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.0.8

3 years ago

0.0.5

3 years ago

0.0.4

3 years ago

0.0.7

3 years ago

0.0.6

3 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago