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

hyperscript-helpers

v3.0.3

Published

Terse syntax for hyperscript

Downloads

4,656

Readme

hyperscript-helpers

Terse syntax for hyperscript.

Less than 50 lines of code, taking your hyperscripting to the next level.

What is it

hyperscript-helpers elm-html inspired helpers for writing hyperscript or virtual-hyperscript.

They work with React.createElement, but there is also a feature-rich hyperscript library for React: react-hyperscript.

// instead of writing
h('div')

// write
div()

// instead of writing
h('section#main', mainContents)

// write
section('#main', mainContents)

hyperscript-helpers vs templates (including JSX)

With hyperscript-helpers:

  • It's nice to use functional utilities like lodash, because it's just functions
  • You get errors if you misspell a tag name, because they are function names
  • You have a consistent syntax at all times, because markup is just functions
  • Also, it's just functions

This is super helpful, especially when using hyperscript-helpers with Cycle.js!

See the supported TAG_NAMES here: src/index.js.

Example

Suppose we have a list of menu items of:

{ title: String, id: Number }

and a function that returns attributes given an id:

function attrs(id) {
  return { draggable: "true", "data-id": id };
}

How would we render these in plain hyperscript, JSX or with the helpers?

// plain hyperscript
h('ul#bestest-menu', items.map( item =>
  h('li#item-'+item.id, attrs(item.id), item.title))
);

// JSX
<ul id="bestest-menu">
  {items.map( item =>
    <li id={"item-"+item.id} {...attrs(item.id)}>{item.title}</li>
  )}
</ul>

// hyperscript-helpers
ul('#bestest-menu', items.map( item =>
  li('#item-'+item.id, attrs(item.id), item.title))
);

How to use

npm install hyperscript-helpers

The hyperscript-helpers are hyperscript-agnostic, which means there are no dependencies. Instead, you need to pass the implementation when you import the helpers.

Using ES6 :sparkling_heart:

const h = require('hyperscript'); // or 'virtual-hyperscript'
const { div, span, h1 } =
  require('hyperscript-helpers')(h); // ← Notice the (h)

With React

// ✅ Preferred
const h = require('react-hyperscript');
const React = require('react');
const { div, span, h1 } =
  require('hyperscript-helpers')(h); // ← Notice the (h)


// Also works, but beware of the createElement API
const React = require('react');
const { div, span, h1 } =
  require('hyperscript-helpers')(React.createElement); // ← Notice the (React.createElement)

Using ES5

var h = require('hyperscript'); // or 'virtual-hyperscript'
var hh = require('hyperscript-helpers')(h);  // ← Notice the (h)
// to use the short syntax, you need to introduce them to the current scope
var div  = hh.div,
    span = hh.span,
    h1   = hh.h1;

Once that's done, you can go and use the terse syntax:

$ node
▸ const { div, span, h1 } = require('hyperscript-helpers')(require('hyperscript'));
◂ undefined

▸ span('😍').outerHTML
◂ '<span>😍</span>'

▸ h1({ 'data-id': 'headline-6.1.2' }, 'Structural Weaknesses').outerHTML
◂ '<h1 data-id="headline-6.1.2">Structural Weaknesses</h1>'

▸ div('#with-proper-id.wrapper', [ h1('Heading'), span('Spanner') ]).outerHTML
◂ '<div class="wrapper" id="with-proper-id"><h1>Heading</h1><span>Spanner</span></div>'

API

Because hyperscript-helpers are hyperscript-agnostic there is no "exact" API. But, just to give you a direction of what should be possible:

tagName(selector)
tagName(attrs)
tagName(children)
tagName(attrs, children)
tagName(selector, children)
tagName(selector, attrs, children)

Where

  • selector is string, starting with "." or "#".
  • attrs is an object of attributes.
  • children is a hyperscript node, an array of hyperscript nodes, a string or an array of strings.

hyperscript-helpers is a collection of wrapper functions, so the syntax of your exact hyperscript library (like virtual-hyperscript) still applies.

For example, for multiple classes:

// ... with Matt-Esch/virtual-dom/.../virtual-hyperscript
button({className: "btn btn-default"}); // ← separated by space!
button(".btn.btn-default");             // ← separated by dot!

Other hyperscript libraries may have other syntax conventions.

Potential issues

Selector shortcut

The selector shortcut (div('.my-class')) may cause unexpected results in some cases. Our suggestion is:

Whenever you use tagName(<children>) syntax and <children> may be a string, starting with . (period) or # (number sign), wrap the argument in [].

// ✅ GOOD
filenames.map(filename => span([filename])); // <span>README.md</span><span>.gitignore</span>

// ❌ BAD
filenames.map(span); // <span>README.md</span><span class="gitignore"></span>

As most hyperscript is written by hand, we decided keep this convenient shortcut despite the issue.

Logic in class names

If you need to apply logic rules for class generation, we recommend using libraries like classnames for making proper {className: ...} argument.

Not recommended:

span(error ? ".error" : null);         // ← may be a trap, because:
span(error ? ".error" : null, {}, []); // ← this one is wrong

Tools

html-to-hyperscript.paqmind.com – webservice to convert HTML to hyperscript

Contributing

To get set up, simply clone the repository, navigate to the directory on your terminal and do the following:

# install dependencies
npm install

# build the project
npm start

# run tests
npm test

# commit your changes with commitizen
npm run commit
# or "git cz", if you have commitizen in your PATH

The source code can be found under the src directory, and the built file is under dist.

Tests are written with Mocha, using the awesome JSVerify library.


hyperscript-helpers is brought to you by @ohanhi.

License: MIT