Have ideas to improve npm?Join in the discussion! »

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

    0.1.10 • Public • Published

    DOMK

    Powerful DOM toolkit

    Installation

    npm install domk --save
    

    Why domk ?

    • Domk is made for small and medium projects.
    • Domk is the best fit for SSR projects.
    • No boilerplate, principle, configuration needed.
    • With Domk you can manipulate DOM easier and more flexible.
    • Domk is an alternative for jQuery or static template engines.
    • Domk is very compact, only 3kb after GZiped

    Getting started

    Let's create simple clock app

    import domk from "domk";
     
    document.body.innerHTML = `<h1></h1>`;
     
    // create date formatter
    const formatter = new Intl.DateTimeFormat("en", {
      hour12: true,
      hour: "numeric",
      minute: "2-digit",
      second: "2-digit",
    });
     
    const Clock = domk.one(
      // select h1 element, the first argument is query selector text
      // if there are many h1 elements in the document,
      // the first one will be selected because we call domk.one()
      // using domk.all() to update multiple matched elements at once
      "h1",
      // define updates for selected elements
      function () {
        return {
          // update element text
          text: formatter.format(new Date()),
        };
      }
    );
     
    // call Clock.update every 1 second
    setInterval(Clock.update, 1000);

    We can make the above example more compact

    setInterval(
      domk.one("h1", () => ({ text: new Date().toString() })).update,
      1000
    );

    Click counter app

    import domk from "domk";
     
    let count = 0;
    let Counter;
     
    document.body.innerHTML = `<button></button>`;
     
    function handleClick() {
      count++;
      Counter.update(count);
    }
     
    Counter = domk.one(
      "button",
      // model is value of count
      function (model) {
        return {
          text: model
            ? `Clicked ${model} ${model === 1 ? "time" : "times"}`
            : "Click here",
          // define event listeners
          on: {
            // click event
            click: handleClick,
          },
        };
      }
    );
     
    Counter.update(count);

    List rendering

    In this example, we create a list of youtube links, Domk does not generate HTML tags automatically (like React, Angular do), We must provide some existing tags, those will be used for templating

    let cats = [
      { id: "J---aiyznGQ", name: "Keyboard Cat" },
      { id: "z_AbfPXTKms", name: "Maru" },
      { id: "OUtn3pvWmpg", name: "Henri The Existential Cat" },
    ];
     
    // UL is list container
    // The first child of UL will be used for templating
    document.body.innerHTML = `
    <h1>The Famous Cats of YouTube</h1>
    <!-- UL is list container -->
    <ul>
      <li>
        <a target="_blank" ></a>
      </li>
    </ul>
    `;
     
    // define Cat component, no update() call needed
    // when the Cat component is created, it is just like a template
    // it will be called later on by another component
    const Cat = domk.one("a", (cat) => ({
      href: `https://www.youtube.com/watch?v=${cat.id}`,
      text: `${cat.index}${cat.name}`,
    }));
     
    domk
      .one("ul", (cats) => ({
        children: {
          // define model for children
          model: cats.map((cat, index) => ({ ...cat, index: index + 1 })),
          // each child element will be updated by Cat component
          update: Cat,
        },
      }))
      .update(cats);

    Benchmark

    Advanced Usages

    References

    domk(options)

    Create a new Domk component with specified options.

    • options (optional): A plain object has following properties
      • model (optional): A function returns current model or a model object
      • container (optional): A dom node or query selector string. By default, domk uses document as container
    • return: Domk component
    const mutableTodos = [];
    let immutableTodos = [];
     
    domk({ model: mutableTodos });
    domk({ model: () => immutableTodos });
    domk({ container: "#app" });
    domk({ container: document.body });

    domk.one(selector, updateFn) & domk.all(selector, updateFn)

    Query single (domk.one) or multiple elements (domk.all) and apply updating specs to matched elements.

    • selector: A valid query selector string that can be used to querySelector() and querySelectorAll()
    • updateFn: A function retrieves 2 arguments model and context and returns updating specs.

    Domk component

    An object contains all update specs for specified element

    .one(selector, updateFn) & Domk.all(selector, updateFn)

    Perform the same as domk.all and domk.one

    .update()

    • Domk.update(model, container)

    • Domk.update(container)

    model()

    • model(props)

    • model(props, reducer)

    • model(reducer)

    domk.nested()

    • domk.nested(modelFn)

    domk.children()

    • domk.children(modelFn)

    • domk.children(modelFn, component)

    • domk.children(modelFn, updateFn)

    • domk.children(modelFn, keyFn, component)

    • domk.children(modelFn, keyFn, updateFn)

    Updating specs

    A plain object has following properties

    id

    Update element id attribute

    domk.one("div", () => ({ id: "new-id" })).update();
    <div id="new-id"></div>

    name

    Update element name attribute

    class

    Update element class. A value can be string or class map object.

    let isVisible = false;
    domk.one("div.box1", () => ({ class: { hide: !isVisible } })).update();
    domk
      .one("div.box2", () => ({ class: isVisible ? "visible" : "invisible" }))
      .update();
    <div class="box1 hide"></div>
    <div class="box2 invisible"></div>

    domk does not remove original classes (box1, box2), it just append updated classes (hide, visible, invisible)

    style

    Update element style. A value can be string or style map object.

    domk.one("div.box1", () => ({ style: "font-weight: bold" })).update();
    domk.one("div.box2", () => ({ style: { opacity: 0.5 } })).update();
    <div class="box1" style="font-weight: bold"></div>
    <div class="box2" style="opacity: 0.5"></div>

    domk does not add browser prefixes automatically

    selected

    Update selected property of option element

    checked

    Update checked property of input element

    disabled

    Update disabled property of input element

    value

    Update value property of input element

    href

    Update href attribute of anchor element

    text

    Update textContent property of html element

    domk.one("div", { text: "<strong>This is formatted text</strong>" }).update();
    <div>&lt;strong&gt;This is formatted text&lt;/strong&gt;</div>

    html

    Update innerHTML property of html element

    domk.one("div", { html: "<strong>This is formatted text</strong>" }).update();
    <div><strong>This is formatted text</strong></div>

    init

    An init value for a current node. Init value can be function, Node object or HTML string.

    • A function retrieves current node object as first argument.
    • HTML string: Node contents will be replaced with given value.
    • Node object: Clone of given node will be appended to current node.
    domk
      .one("div.box1", { init: "<strong>This is formatted text</strong>" })
      .update();
     
    domk.one("div.box2", { init: document.querySelector("#content") }).update();
     
    const Box3 = domk.one("div.box3", {
      init(node) {
        console.log(node.innerHTML); // Box 3 contents
      },
    });
     
    // init action invoked once
    Box3.update();
    Box3.update();
    Box3.update();
    <div id="content"><button>Click me</button></div>
     
    <div class="box1"><strong>This is formatted text</strong></div>
     
    <div class="box2">
      <div id="content"><button>Click me</button></div>
    </div>
     
    <div class="box3">Box 3 contents</div>

    on

    Update event listeners

    domk
      .one("div", {
        on: {
          click() {
            alert("Hi there");
          },
          mouseover(e) {
            console.log("You are hovering", e.target);
          },
          mouseout(e) {
            console.log("You leave", e.target);
          },
        },
      })
      .update();

    prop

    Update multiple properties at once

    domk.one("button", { prop: { disabled: true, value: "Click me" } }).update();

    attr

    Update multiple attributes at once

    domk.one("a", {
      attr: {
        href: "http://google.com",
        title: "Click me",
      },
    });

    children

    Update the child node of the current node according to the specified model.

    domk
      .one(".list1", {
        children: {
          model: [1, 2, 3],
          update: (number) => ({ text: number }),
        },
      })
      .update();
     
    domk
      .one(".list2", (letters) => ({
        children: {
          model: letters,
          update: (letter) => ({ text: letter }),
        },
      }))
      .update(["A", "B", "C"]);

    Before updating

    <ul class="list1">
      <!-- LI element is used to templating -->
      <li></li>
    </ul>
     
    <ul class="list2">
      <!-- LI element is used to templating -->
      <li></li>
    </ul>

    After updating

    <ul class="list1">
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
     
    <ul class="list2">
      <li>A</li>
      <li>B</li>
      <li>C</li>
    </ul>

    Dependencies

    Nothing

    Install

    npm i domk

    DownloadsWeekly Downloads

    8

    Version

    0.1.10

    License

    ISC

    Unpacked Size

    66.9 kB

    Total Files

    12

    Last publish

    Collaborators

    • avatar