Skip to content

Latest commit

 

History

History
193 lines (153 loc) · 5.83 KB

prax_readme.md

File metadata and controls

193 lines (153 loc) · 5.83 KB

Overview

prax.mjs provides a very simple and performant system for rendering DOM/XML/HTML. It was originally React-inspired, but semantics are much simpler and more universally useful.

Isomorphic SSR is supported via lightweight and performant dom_shim. Pairing these modules together, and using custom DOM elements, provides a good foundation for hybrid SSR/SPA.

Short overview of features:

  • Directly create DOM nodes.
    • No string templates.
    • No VDOM.
    • Can instantiate with new.
  • Convenient syntax. Nice-to-use in plain JS.
    • No templates.
    • No string parsing.
    • No need for JSX.
    • No need for a build system.
  • Render only once. Use native custom elements for state.
    • Use dom_reg for automatic element registration.
  • Good for SSR/SPA hybrids.

Complemented by:

TOC

Usage

Rendering is done via Ren. You must create an instance, which should be a singleton. You can also subclass Ren and override individual methods to customize its behavior.

Browser example:

import * as p from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'
import {A} from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'

const ren = p.Ren.native()
const {E} = ren

document.body.append(
  E.div.props(A.id(`main`).cls(`outer`)).chi(
    E.p.props(A.cls(`inner`)).chi(
      `hello `,
      `world!`,
    ),
  ),
)

/*
The following elements (not strings) have been appended:

<div id="main" class="outer">
  <p class="inner">hello world!</p>
</div>
*/

For string rendering, use .outerHTML:

import * as p from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'
import {A} from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'

const ren = p.Ren.native()
const {E} = ren

// Note the `.outerHTML` call at the end.
console.log(
  E.div.props(A.id(`main`).cls(`outer`)).chi(
    E.p.props(A.cls(`inner`)).chi(
      `hello `,
      `world!`,
    ),
  ).outerHTML,
)

/*
<div id="main" class="outer">
  <p class="inner">hello world!</p>
</div>
*/

Usage with custom elements. The methods .props and .chi are provided by patching the prototype of the given base element class, which is entirely opt-in.

import * as p from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'
import {A} from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'
import * as dr from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/dom_reg.mjs'

const ren = p.Ren.native()

class SomeLink extends dr.MixReg(HTMLAnchorElement) {
  init(href, text) {
    return this
      .props(A.href(href).cls(`link`))
      .chi(text)
  }
}

document.body.append(
  new SomeLink().init(`/some-path`, `click me!`),
)

SSR

For SSR/SPA hybrids, configure an importmap or bundler to choose the right "dom globals" for the right environment, and pass those globals to the Ren you're instantiating. The rest will just work.

import * as p from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'

// Choose the right one.
import * as dg from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/dom_glob_shim.mjs'
import * as dg from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/dom_glob_native.mjs'

const ren = p.Ren.from(dg.glob)

Rendering a complete document with doctype:

import * as p from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/prax.mjs'
import * as dg from 'https://cdn.jsdelivr.net/npm/@mitranim/js@0.1.53/dom_glob_shim.mjs'

const ren = p.Ren.from(dg.glob)
const {E} = ren
const A = p.PropBui.main

console.log(p.renderDocument(
  E.html.props(A.lang(`en`)).chi(
    E.head.chi(
      E.link.props(A.rel(`stylesheet`).href(`/styles/main.css`)),
      E.title.chi(`page title`),
    ),
    E.body.chi(
      E.main.props(A.cls(`main`)).chi(
        `hello world!`,
      ),
    ),
  ),
))

/*
<!doctype html><html lang="en"><head><link rel="stylesheet" href="/styles/main.css" /><title>page title</title></head><body><main class="main">hello world!</main></body></html>
*/

API

Undocumented

The following APIs are exported but undocumented. Check prax.mjs.