domez
TypeScript icon, indicating that this package has built-in type declarations

0.0.5 • Public • Published

DOMEZ

A tiny lib for DOM rendering

Installation

with NPM

npm i domez --save

with YARN

yarn add domez

Features

  • No boilerplate
  • No bundler
  • Tiny size (5KB)

Motivation

There are many frameworks for DOM manipulation like React, Angular, Vue, etc. they are difficult to learn and cumbersome. Domez was born to process the DOM rendering with ease, instead of using Vanilla JS. Domez also makes debugging convenient and easy. It is also compatible with many CSS Frameworks like Tailwind JS, Bootstrap JS

Recipes

Hello World

With DOMEZ

import { render } from "domez";

// define App block builder, the builder returns HTML template that will be rendered into the container
const App = ({ ref }) => {
  // handle button click event
  const buttonRef = ref({ onclick: () => alert("Hello World. " + new Date()) });
  return `<button ${buttonRef}>Greeting</button>`;
};

// use body as rendering container
render(document.body, App);

Compare to Vanilla JS

const App = () => {
  document.body.innerHTML = `<button id="greeting">Greeting</button>`;
  document.getElementById("greeting").onclick = () =>
    alert("Hello World. " + new Date());
};

App();

As you see, if we use Vanilla JS, the app code looks verbose, hard to mainternant and extend. Let's see complex example

Simple Todo App

import { render } from "domez";

const Todo = ({ ref }, todo) => {
  // a block builder can return a controller object
  // the controller object must have template property, it uses to render the block
  return {
    // expose the todo object for external access
    todo,
    template: `<div ${ref({ onclick: todo.onRemove })}>${todo.id}: ${
      todo.title
    }</div>`,
  };
};

const App = ({ list, ref }) => {
  let uniqueId = 1;
  const inputRef = ref();
  // create a element list and specific builder for each item
  const todoList = list(Todo);
  const handleAdd = () => {
    const id = uniqueId++;
    // inputRef() returns current ref of target element
    const title = inputRef().value;
    // remove an list item that has id equals to current todo id
    // the list item is block controller that returns from block builder function
    const onRemove = () =>
      todoList.remove((todoController) => todoController.todo.id === id);
    // this param will be passed to Todo builder as second parameter
    // after creating the child block, the list will store the block controller for later use
    const param = { id, title, onRemove };
    todoList.push(param);
    inputRef().value = "";
    inputRef().focus();
  };

  return `
  <div>
    <input ${inputRef} /><button ${ref({ onclick: handleAdd })}>Add</button>
    ${todoList}
  </div>
  `;
};

render(document.body, App);

Compare to Vanilla JS

const createTodo = (todo) => {
  const div = document.createElement("div");
  div.onclick = () => div.remove();
  div.textContent = `${todo.id} ${todo.title}`;
  return div;
};

const App = () => {
  let uniqueId = 0;

  document.body.innerHTML = `
    <input id="input"/><button id="button">Add</button>
    <div id="list"></div>
    `;
  const $input = document.getElementById("input");
  const $button = document.getElementById("button");
  const $list = document.getElementById("list");

  $button.onclick = () => {
    const id = uniqueId++;
    const title = $input.value;
    const $todo = createTodo({ id, title });
    $list.appendChild($todo);
    $input.value = "";
    $input.focus();
  };
};

App();

Using element ref

const App = ({ ref, effect }) => {
  const divRef = ref();

  // WRONG: the div ref is not ready here
  divRef().textContent = "Hello World";

  // RIGHT: use effect to make sure all refs are ready to use
  effect(() => {
    divRef().textContent = "Hello World";
  });

  return `<div ${divRef}></div>`;
};

Set initial props/style for specified element

const App = ({ ref }) => {
  return `<div ${ref({
    text: "Hello World", // OR you can set inner HTML { html: '<i>Hello World</i>' }
    style: "color: red", // OR { style: { color: 'red' } }
    onclick: () => alert("Hello World"),
    // OR { class: 'my-class' }
    class: {
      btn: true,
      "btn-primary": true,
    },
  })}></div>`;
};

// that equipments to this
const App = ({ ref, effect }) => {
  const divRef = ref();

  effect(() => {
    divRef().textContent = "Hello World";
    divRef().onclick = () => alert("Hello World");
    divRef().classList.add("btn");
    divRef().classList.add("btn-primary");
    divRef().style.cssText = "color: red";
  });

  return `<div ${divRef}></div>`;
};

Caveats

Do not use self closing tag

Some frameworks accept self-closing tag for shorter code but this might lead to unexpected error if you use it with DOMEZ

WRONG

template = `<h1/>`;

RIGHT

template = `<h1></h1>`;
// it's ok
template = `<input/>`;

Package Sidebar

Install

npm i domez

Weekly Downloads

0

Version

0.0.5

License

ISC

Unpacked Size

91.5 kB

Total Files

7

Last publish

Collaborators

  • linq2js