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

@internet/dom

v1.3.0

Published

Experimental React-like library to build DOM

Downloads

3

Readme

DOM Library

:books: Documentation | :tada: Example | :globe_with_meridians: Internet modules

  • :warning: Experimental React-like library to build DOM, without setState and patching.
  • Own JSX implementation using h pragma.
  • render method to render and mount jsx
  • cloneElement to clone a virtual node with new props or new children
  • Class Component with react-like lifecycle methods.
  • Callback refs support.
  • You can also render "real" HTML Elements inside virtual dom
    • This is useful to add a Component-oriented architecture on top of an already existing html page (like rendered from PHP)

:warning: Warnings

  • This is not a React alternative, use preact for this purpose.

  • You can render "real" HTML Element inside virtual dom (using render or component.render)

    • It's the one of the reasons why there isn't patching
    • It's a great feature to add a Component-oriented architecture on top of an already existing html page (like rendered from PHP)
    • It also means that the virtual dom is absolutely not a source of thruth :warning::warning:
    • It can be super easy to have leaks and a bad lifecycle behaviour, so don't rely too much on this lib
  • There is no event management for now. Use addEventListener / removeEventListener with lifecycle methods to be sure of what you are doing.

  • render have different arguments than the preact / React one.

  • component.render is used to render portions of jsx inside it, as child of the component

    • the initial rendering of the component is made via the component.template method instead

Requirements

Installation

# using npm
$ npm install --save @internet/dom

# or using yarn
$ yarn add @internet/dom

API

import { h, render, Component, cloneElement, addRef } from '@internet/dom'

:pencil: h([tag|Component], [props={}], ...children)

Creates a VNode (virtual DOM element).

Kind: global function
Returns: object - A vnode object containing its type, props, children and some flags

| Param | Type | Default | Description | | --- | --- | --- | --- | | nodeName | string | function | | A tagname or a component. e.g. 'div', 'a', Component | | [props] | object | {} | Attributes/props to set on the created element. | | [...children] | Array.<VNode> | [] | All additional arguments are vnode children |

Example

import { h, render } from '@internet/dom'

// Create a new vnode using JSX (via Babel or Bublé)
const node = <div style="color: red">Hello</div>

// The same node can be made using directly the `h` function
const node = h('div', { style: 'color: red' }, 'Hello')

// render the created node into <body>
render(node, document.body)

:movie_camera: render(VNode, parent)

Renders a virtual node and mount-it into a parent Element

:warning: render always dispatch lifecycle events. Even if you don't pass a parent as 2nd argument, all componentDidMount methods and callback refs will be called. Be carreful!

:warning: If you render a virtual node inside an already mounted component, use its component.render method instead. Otherwise, the rendered subcomponents and callback refs will not be register as "childs" of the parent component. This can lead to bad lifecycle dispatching if you destroy the parent for instance.

Kind: global function
Returns: object - Return an object containing:

  • result.nodes : Array of rendered DOM nodes
  • result.components : First-level components instances
  • result.refs : First-level callback refs

| Param | Type | Description | | --- | --- | --- | | vnode | object | A (JSX) VNode to render | | [parent] | HTMLElement | function | DOM Element to render into. You can also use a callback function: the function will be called with DOM Elements to mount as first argument | | [parentComponent] | Component | The parent component instance where the vnode will be mounted. You can directly use parentComponent.render(vnode, parent) |

Example

import { h, render } from '@internet/dom'
import App from 'components/App'

// Instanciate an App component and append it to document.body
render(<App />, document.body)

// Insert a new div into document.body, before the first child of document.body
render(<div>Some text</div>, div => {
  document.body.insertBefore(div, document.body.firstChild)
})

:orange_book: Component class

Example

import { h, Component, render } from '@internet/raf'

class App extends Component () {
   template () {
     return (
       <div>
         <p>My first app</p>
       </div>
     )
   }

   componentDidMount () {
     console.log('App is mounted')
     console.log('HTMLElement of the App: ', this.base)
   }
}

// Mount a new instance of App component into document.body
// Will call componentWillMount, template and componentDidMount lifecycle events
render(<App />, document.body)

Component API

new Component([props])

Create a new Component

| Param | Type | Default | Description | | --- | --- | --- | --- | | [props] | object | {} | Component properties / attributes. Can also contains children. |


component.template([props]) ⇒ VNode | HTMLElement

component.template will be called during the component initial rendering to create the component.base node

Kind: instance method of Component
Returns: VNode | HTMLElement - VNode (JSX or h calls) or real HTMLElement that will be rendered as the component.base node. You can also return an array of elements.
Category: Methods

| Param | Type | Default | Description | | --- | --- | --- | --- | | [props] | object | {} | component.props automatically passed as argument. |

Example

import { h, Component, render } from '@internet/dom'

class HelloDiv extends Component {
  template () {
    // will create a new p tag
    return <div>Hello!</div>
  }
}
// Append a new "Hello!" div to document.body
render(<HelloDiv/>, document.body)

class MainComponent extends Component {
  template () {
    // use the existing <main> node as the component base
    return document.querySelector('main')
  }
}

// Create a new MainComponent, using an already existing dom node
render(<MainComponent />)

component.componentWillMount([props])

component.componentWillMount will be called by render just before a the component template rendering

Kind: instance method of Component
Category: Methods

| Param | Type | Default | Description | | --- | --- | --- | --- | | [props] | object | {} | component.props automatically passed as argument. |


component.componentDidMount([props])

component.componentDidMount will be called by render when all the rendered dom tree is mounted

Kind: instance method of Component
Category: Methods

| Param | Type | Default | Description | | --- | --- | --- | --- | | [props] | object | {} | component.props automatically passed as argument. |


component.componentWillUnmount([props])

component.componentWillUnmount will be called when the component or one of its ancestors is destroyed

Kind: instance method of Component
Category: Methods

| Param | Type | Default | Description | | --- | --- | --- | --- | | [props] | object | {} | component.props automatically passed as argument. |


component.render(vnode, [parent]) ⇒ object

Render a vnode or array of vnodes and register the rendered content as "child" of this component. Use this method when you want to add content to the component after the initial rendering. This ensures new items will be correctly unmount when the component is destroyed.

Kind: instance method of Component
Returns: object - Return an object containing rendered nodes, components and refs
Category: Methods

| Param | Type | Description | | --- | --- | --- | | vnode | object | A (JSX) VNode to render | | [parent] | HTMLElement | function | DOM Element to render into. You can also use a callback function: the function will be called with DOM Elements to mount as first argument |

Example

import { h, Component, render } from '@internet/dom'

class Item extends Component {
  template () {
    return <li>Item</li>
  }
}

class List extends Component {
  template () {
    return (
      <div>
        <ul ref={el => { this.ul = el }}></ul>
        <button ref={el => { this.button = el }}>Add Item</button>
      </div>
    )
  }

  addItem () {
    // Render a new Item instance and add it to the list
    // All created Items will be properly destroyed when the List instance is removed
    this.render(<Item />, this.ul)
  }

  componentDidMount () {
    this.addItem = this.addItem.bind(this)
    this.button.addEventListener('click', this.addItem)
  }

  componentWillUnmount () {
    this.button.removeEventListener('click', this.addItem)
  }
}

render(<List />, document.body)

component.destroy()

Destroy the component and its children components.

  • This also removes component props and de-reference the component from its parent.
  • Callback refs inside the component tree will be called with null as first argument
  • Set component.mounted to false

Kind: instance method of Component
Category: Methods
Example

import { h, Component, render } from '@internet/dom'

class SelfDestructButton extends Component {
  template() {
     return <button>Destroy me</button>
  }

  componentDidMount() {
    this.destroy = this.destroy.bind(this)
    this.base.addEventListener('click', this.destroy)
  }

  componentWillUnmount() {
    this.base.removeEventListener('click', this.destroy)
  }
}

render(<SelfDestructButton />, document.body)

component.props : object

Contains all component properties and children. Do not modify it directly, but recreate a new component using cloneElement instead

Kind: instance property of Component
Category: Properties


component.base : VNode | HTMLElement | array

HTMLElement used as "base" for the component instance. Can also be an array of elements if template return an array.

Kind: instance property of Component
Category: Properties


component.mounted : boolean

Set to true when component is mounted

Kind: instance property of Component
Category: Properties


:floppy_disk: cloneElement(VNode, [newProps={}], [newChildren])

Clones the given virtual node, optionally updating its props and replacing its children

Kind: global function
Returns: object - A new vnode object containing updated props / children

| Param | Type | Default | Description | | --- | --- | --- | --- | | vnode | object.VNode | | A virtual node object to clone | | [props] | object | {} | Attributes/props to set on the created element. | | [...children] | Array.<VNode> | [] | All additional arguments are vnode children |

Example

import { h, render, cloneElement } from '@internet/dom'

const useRed = (vnode) => cloneElement(vnode, { style: 'color:red;' })

const normalText = <p>Some text</p>
const redText = useRed(normalText)

render(redText, document.body)

:mag: addRef(obj, refName)

Create a callback ref function

Kind: global function
Returns: function - A callback ref function

| Param | Type | Description | | --- | --- | --- | | obj | object | function | Object or Component instance to add the reference to | | refName | string | Name of the reference. Will be accessible from obj[refName] |

Example

import { h, render, addRef, Component } from '@internet/dom'

class App extends Component () {
  template () {
    return (
      <div>
        <button ref={addRef(this, 'button')}>A button</button>
      </div>
    )

    componentDidMount () {
       console.log('Button is mounted:', this.button)
    }
  }
}

render(<App />, document.body)