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

pico-dom

v1.0.1

Published

small DOM component system

Downloads

76

Readme

pico-dom

minimalist tool for dynamic DOM tree and component creation, updates, events and lifecycles functions. Supports svg, namespace, keyed lists, and conditional elements, all in 2kb gzip, ES5, no dependencies. Support direct use in browser, CJS and ES modules

ExampleWhyAPILicense

Example

supports different environments

  • CJS: require('pico-dom').element
    • can also be used server-side. See setDocument below
  • ES modules: import {element} from 'pico-dom'
  • browser: (picoDOM.element)*
import {D, element as el, list} from '../module'
import {Store} from './Store' // any user store will do
import {ic_remove, ic_add} from './icons'

var store = new Store([]),
		i = 0,
		j = 0

var table = el('table',
	el('caption', {class: 'f4'}, 'table example with...'),
	el('tbody',
		list(
			el('tr',
				function() { i = this.key },
				el('td', //leading column with icon
					function() { this.i = i },
					{ events: { click: function() { this.root.store.delRow(this.i) } } },
					ic_remove
				),
				list( // data columns
					el('td',
						function() { j = this.key },
						el('input',
							function() {
								this.i = i; this.j = j
								this.update = function(v) { this.node.value = v }
								this.event('change', function() {
									this.root.store.set(this.node.value, [this.i, this.j])
								})
							}
						)
					)
				)
			)
		),
		el('tr',
			el('td',
				{ events: {click: function() { this.root.store.addRow() } } },
				ic_add
			)
		)
	)
).create()
.extra('store', store)
.moveTo(D.body)

store.onchange = function() { table.update( store.get() ) }
store.set([
	['icons', 'SVG icons'],
	['keyed', 'keyed list'],
	['store', 'data flow'],
	['event', 'event listeners']
])

Why

To explore ideas for a flexible and concise API with minimal tooling and memory footprint.

Features

  • dynamic lists and nested lists (keyed, indexed or select)
  • svg and namespace support
  • ability to inject a document API for server use and/or testing (e.g. jsdom)
  • no virtual DOM, all operations are done on actual nodes
  • 2kb gzip, no dependencies, all under 600 lines including comments and jsDocs
  • all text injections and manipulations done through the secure textContent and nodeValue DOM API
  • available in CommonJS, ES6 modules and browser versions
  • All in ES5 with ES modules, CJS module and iife for browsers. Should work well on mobile and older browsers like IE9.

Limitations

  • view and event helpers only
  • limited css utility
  • strictly DOM element creation and manipulation (no router, no store)

API

Templates

A template is an immutable set of instructions to generate multiple components.

Element templates

  • element(tagName [, ...options|children|transforms])
  • elementNS(nsURI, tagName [, ...options|children|transforms])
  • svg(tagName [, ...options|children|transforms])

Node template

  • text(textContent [, ...options|transforms])
  • template(node, [, ...options|transforms])

List template

  • list(template, [, ...options|transforms])

The 6 template generating functions take the following types of arguments:

  • options: Object to define future operations {methodName: arguments} upon component creation. Examples

    • {class: 'abc'} to set the component node class attribute once an element component is created
    • {attrs: {id: 'abc'}} to set component node attributes once an element component is created
    • {events: {click: function() { this.text('CLICKED!') } }} to set element component event listeners
    • {props: {id: 'abc'}} to set component node properties
    • {extras: {someKey: someValue}} to set component properties on the component itself
  • transforms are just functions called with the component context. Examples

    • function() { this.class('abc') } to set the component node class attribute once an element component is created
    • function() { this.attr(id: 'abc') } to set component node attributes once an element component is created
    • function() { this.event('click', handler) } to set element component event listeners
  • children can be templates, nodes or numbers and strings to be converted to text nodes. Same as using the {append: [...]} option

Templates have a number of chainable methods that generate new templates (templates are immutable). The methods are the same as the option keys listed above with additional methods that take more than one argument.

  • element attributes: .attr(key, val), .attrs({key, val})
  • element children: .append(node, number, string, template)
  • element event listeners: .event(name, callback), .events({name, callback})
  • node properties: .prop(key, val), .props({key, val})
  • component properties: .extra(key, val), .extras({key, val})
  • component operations: .call(funtion() {})

List

List are special components representing a group of multiple nodes.

Resizable lists take a single template that will be used to generate list of varying sizes

  • list(template) to create dynamic indexed set of nodes based on the size of the array upon updates
  • list(template, {getKey: function(v) {return v.id}}) for a keyed list

Select lists have predefined templates that are used to conditionally display subsets on updates

  • list({a: templateA, b:templateB}, {select: function(v) {return [v.id]}}) created a conditional list template

lists can be stacked and nested.

Components

Components are created from templates: template.create(). Normally, only the main component is manually created and all other templates are initiated from within.

In addition to the same methods found in templates (attr(s), extra(s), call, append, class, event), Components have the following properties and methods for dealing with DOM Nodes

DOM references

  • .node: the associated DOM node or anchor node for lists
  • .root: the root component that created the component. (null for the main one created by the user)

DOM functions

  • .moveTo(parent [,before]): to move a component
  • .remove(): to remove a component from the DOM
  • .destroy(): to remove a component and remove listeners

Update Functions

  • .text(v): to set the node textContent of element Component
  • .update(...) the function to trigger changes based on external data
  • .updateChildren(..) to pass update data down the tree.

By default, update is set to text for text components and updateChildren for the rest. Normally, only the main component is updated and the update trickles down the DOM tree according the the rules predefined in the templates.

Other

  • .key key for identification and sorting. Set by parent lists on componet children
  • .refs: used in list to hold node references
  • .getKey(val, key, arr) => string: to get the unique key for keyed lists
  • .select(val, key) => array: array of keys for conditional/select lists

Lifecycle operations

Lifecycle hooks are not provided directly but can be acheived by wrapping component methods

  • on creation: template.call(...)
  • on insert: template.call(...) or wrap component.moveTo(...)
  • on remove: wrap component.remove()
  • on destroy: wrap component.destroy()
var textTemplate = text('ABC', function() {
  var item = this,
      remove = item.remove
  this.remove = function() {
    window.requestAnimationFrame(remove.call(item))
  }
})

Other helpers

  • setDocument(document) to set the Document interface for testing or server use
    • eg. setDocument((new JSDOM).window.document)
  • D reference to the Document interface for testing or server use
    • eg. var body = D.body
  • find(from [, test] [, until]) find a component within nodes or components and matching the test function. It parses nodes up and down following the html markup order.
    • eg. find(document.body) to get the first component in the document
    • eg. find(tableComponent, function(c) { return c.key === 5 } )
  • css(ruleText) to insert a rule in the document for cases where an exported template relies on a specific css rule that is not convenient or practical to include in a seperate css file

License

MIT © Hugo Villeneuve