npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

neobiz

v4.7.2

Published

A simple tool to convert Object to HTML string

Downloads

49

Readme

Documentation Neobiz.js 4.7.x

A simple view engine that has 100% JS features

Neobiz.js is pure in JS lang, transform Object into HTML

fix error outFIle

Updates:

  • fix event bugs
  • Boolean attributes / non-value attribute (example: disabled, readonly)

prev update:

  • render method change to **\_render**to avoid conflict with another library and add safety check
  • render option props improve
  • fix bug on child order

features:

  • eventHandler
  • Reusable & editable style/css
  • Altering object
  • Registering component
  • Explicit tag name supported

read /example dir to better understanding

for browser usage use browser.js file.

link to usage in express.js


Example with vue in browser

page.js

import "neobiz";

({
  div: {
    script: [
      { src: "https://unpkg.com/vue@3/dist/vue.global.js" },
      { src: "https://unpkg.com/[email protected]/browser.js" },
      { src: "./my-component.js" },
    ],
    id: "app",
  },
  script: {
    html() {
      const { createApp } = Vue;

      createApp(myComponent).mount("#app");
    },
  },
}.outFile("./welcome.html"));

my-component.js

const myComponent = {
  data() {
    return { msg: "hi, this is example" };
  },
  template: { h1: { text: "{{msg}}" } }._render,
};

| properties | caller | return-type | description | | -------------- | ------------------------------------- | ----------- | --------------------------------------- | | _render | Object | string | rendering to HTML | | outFile | Object @params destination[string] | void | generate static HTML file | | range | Array @params length[int], start[int] | Array | shortcut for looping in a range | | repulse | String | Object | generate object from HTML string | | css | Object | Object | generate css from object | | cssText | Object | Object | inline css | | alter [trials] | Object @params cb[function] | Object | altering object before rendering | | reg | Object | void | registring an object | | regm | Object | void | updating the existing registered object | | load | Object | Object | read an existing registered object | | unred | Object | void | removing an existing registered object | | renderOption | Object @params option[Object] | void | set the option for rendering |

Why use this?

  • Easy maintance innerHTML rather than literal string
  • Generate static html file
  • Full control of view. Such as filtering, encrypting the data before serve, or just like conditional and loop case
  • Almost no need to learn anything. Just need to learn how to render
  • Limitless potential, because it's just js. Almost all library should be compatible

Basic syntax

How to use? just import this:

import "neobiz";

It's just an Object! wrap in () to create a statement or just assign to a var

{
  // text property is same as innerText
  h1: {
    text: "Hello World!",
  },
}._render;
// <h1>Hello World!</h1>

or use call method

_render.call({
  // text property is same as innerText
  h1: {
    text: "Hello World!",
  },
});

Comments:

{
  // this is comment
  /*
  this is multi line
  */
  h1: {
    text: "This is heading";
  }
}

properties dom

{
  h1: {
    class:"heading",
    text: "Hello World!",
    style:"color: #DC1E1E",
  }
}
// <h1 class="heading" style="color: #DC1E1E">Hello World!</h1>

boolean attributes

use Null to indicate non-value attributes, do not confuse Null to null

{
    button: { text: "Hello World!", disabled: Null },
  }._render

innerText & innerHTML:

  {
    h1: { text: "<b>this is a text</b>" },
    ul: { html: "<li>this will be render as html</li>" },
  }

nested dom:

{
  body: {
    h1: {
      text: "Hello World!",
    }
  }
}

expression & operator

{
  span: [
    { text: 24 + 12 / 6 },
    { text: !false },
  ],
}

siblings dom:

There is a case like this:

<li>orange</li>
<li>banana</li>

Object can not use 2 keys with the same name

// Don't do this
{
  li:{text:"orange"},
  li:{text:"banana"},
}

// Do this
{
  li:[
    {text:"orange"},
    {text:"banana"},
  ]
}

Render Option

renderOption({
  camelCase: false,
  once: false,
  nodoctype: false,
  ignoreTag: false,
  prefixTag: false,
  prefixAttr: false,
});

set once to true to use option only for once,

set nodoctype to true to remove <!doctype html> in the beninging,

set ignoreTag to true to unused tag properties,

set prefixTag to something to add text before tag, use noprefix:true to skip on specific object

set prefixAttr to something to add text before attribute, use nopAttr:true to skip in specific object

set camelCase true to convert camelCase properties to kebab-case

make sure to set the option before rendering

renderOption({
  camelCase: true,
});

render.call({
  ionRouter: {},
});

result

<ion-router></ion-router>

Explicit tag name

What if there is somethings in the middle of list?

<li>orange</li>
<p>
  <span>This is in the middle</span>
</p>
<li>banana</li>

if we use an array there will share the tag name right? just use this:

use string as key could distinc an element with just a space no need to worry, it will render without space

{
  li:{text:"orange"},
  p:{span:{text:"This is in the middle"}},
  "li ":{text:"banana"},
}

or write the tag name:

{
  li: [
    { text: "orange" },
    { tag: "p", span: { text: "This is in the middle" } },
    { text: "banana" },
  ],
}

also with specifying tag name, we can name it differently:

  {
    PersonList: ["Arthur", "Zoro"].map((person) => ({
      tag: "li",
      text: person,
    })),
  }

Modify an Object

use alter properties, with function as params. no need to return a value

const y = {
  h1: { text: "Hello World!" },
  p: { text: "this is a p" }.alter((e) => (e.class = "lorem")),
}.alter((e) => {
  e.h1.text = "thi is altered text";
  e.h1.style = { color: "red", fontSize: "150%" }.cssText;
});

console.log(y.render);

Components / Partials

import header from "./header.v.js"; //function type
import footer from "./footer.v.js"; //object type

{
  div: header({ user: "dim24" }),
  p: { text: "this is text" },
  div: footer,
}.render;

header.v.js

export default ({ user }) => ({ h1: { text: `Hi, ${user}` } });

footer.v.js

export default {
  script: { src: "/assets/js/main.js" },
  span: { text: "this is footer" },
};

reg, regm, load & unreg Components

The idea is to make object has resuability

reg & load

this function need a single argument to set a name of registering object,

there is 2 ways to registering an component:

  • through properties method:
{ name:"viewport"}.reg("viewport")
  • via call method:
reg.call({ name: "viewport" }, "viewport");

now we can load it's value whenever we want

{
  meta:load("viewport"),
  body: {
  }
}

regm

this function will replace an existing registered object with a new value:

const newValue = load("viewport");
newValue.content = "width=device-width, initial-scale=1.0";

newValue.regm("viewport");

unreg

when we the object doesn't needed anymore, just unreg it:

unreg("viewport");

Style

use camel case to css properties

inline CSS:

{
  h1:{
    text:"Hello World",
    style:{
      color:"#1B73F8",
      fontSize:"150%"
    }.cssText
  }
}

use style :

global-style.js:

export default {
  h1: {
    color: "red",
  },
  body: {
    margin: "0px",
    textAlign: "center",
  },
};

why should use object css rather than direct css?

we can easily modify the style

main-page.js:

import style from "./global-style.js";

style.body.margin = "12px";

{
  style:style.css,
  div:{
    h1:{text:"Hello World!"}
  }
}.render

reusable style / mixin

const flex = (justify, align, direction = "row") => ({
  display: "flex",
  justifyContent: justify,
  alignItems: align,
  flexDirection: direction,
});

const space = {
  padding: "6px 8px",
  margin: "6px 10px",
};

console.log({
  style: { div: flex("center", "center"), button: { border: "none", ...space } }
    .css,
});

Interacting with DOM

use script to interact with browser with html property

wrap the script with a function, or use string

{
  button:{onclick:"sayHi(this)",id:"hi-button"},
  script:{
    html(){
      document.getElementById("hi-button").innerText="Click me!";

      function sayHi(el){
        el.innerText="Hi!";
      }
    }
  }
}

Event

you can add an event this keyword always refered to the node itseft

{
  input:{type:"password",onkeypress(){
    if(event.keyCode==13)
    alert(this.value)
  }},
  button:{text:"Click me!",onclick(){
    this.innerText = this.innerText=="clicked"?"Click me!":"clicked";
  }}
}

Repulse

If you already have an html file and want to modify it, or make it as a template, just use this

this function is still has a lot issues, use only in a simple case

  • need to wrap all tag into a single parent
  • recommended to use external script and css
  • repetitive / nested could caused weird behavior (help me, please!)

I still try to improve this feature. if you can provide some help just tell me please... :)

const { div } = `
<div>
    <h1>Hello dims!</h1>
</div>
`.repulse;

div.id = "main";
div.h1.class = "heading";
div.p = { text: "this is a whole text" };

console.log({ div }.render);

result

<div id="main">
  <h1 class="heading">Hello dims!</h1>
  <p>this is a whole text</p>
</div>

Pass Value

use shorthand anonym function

console.log(((user) => ({ h1: { text: `Hello, ${user}` } }))("Vins").render);

or

const greeting = (user) => ({ h1: `Hello, ${user}` });

console.log(greeting("Vins").render);

Control Flow

ternary:

{
    h1: status
      ? { text: "Hello World!" }
      : {
          a: { href: "#", text: "You are offline!" },
        },
}

IIFE if-else

{
    h1: (() => {
      let result;
      if (status) result = { text: "Hello World!" };
      else
        result = {
          a: { href: "#", text: "You are offline!" },
        };
      return result;
    })(),
}

normal if else

let result;
if (status) result = { text: "Hello World!" };
else
  result = {
    a: { href: "#", text: "You are offline!" },
  };

//use
{
  h1: result,
}

IIFE switch-case

{
    h1: (() => {
      let result;
      switch (status) {
        case true:
          result = { text: "Hello World!" };
          break;
        case false:
          result = {
            a: { href: "#", text: "You are offline!" },
          };
      }
      return result;
    })(),
}

Loop & array manipulation

range & map:


  {
    ul: {
      li: [].range(8, 1).map((item) => ({ text: "data-" + item })),
    },
  }

map

  {
    ul: {
      li: ["grape", "banana", "apple"].map((text) => ({ text })),
    },
  }

filter

{
  ul: {
    li: [].range(8, 1).filter( num => num % 2 == 0 ).map((item) => ({ text: "data-" + item })),
  },
}

for

  {
    ul: {
      li: (() => {
        const result = [];
        for (let i = 1; i < 9; i++) result.push({ text: "data-" + i });
        return result;
      })(),
    },
  }

while

  {
    ul: {
      li: (() => {
        const result = [];
        let i = 0;
        while (++i < 9) result.push({ text: "data-" + i });
        return result;
      })(),
    },
  }

templating

this example use single file usage. for modular usage leave to you, or just read the example dir

//template file
const template = (content) => ({
  div: {
    class: "main wrapper",
    div: content,
  },
});

//content file
template({
  h1: { text: "Hello World!" },
});

Thank you for read until here.