Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ohanhi/hyperscript-helpers
Terse syntax for hyperscript.
https://github.com/ohanhi/hyperscript-helpers
Last synced: 18 days ago
JSON representation
Terse syntax for hyperscript.
- Host: GitHub
- URL: https://github.com/ohanhi/hyperscript-helpers
- Owner: ohanhi
- License: mit
- Created: 2015-07-01T17:40:59.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2020-07-15T20:46:10.000Z (over 4 years ago)
- Last Synced: 2024-09-21T13:49:02.407Z (about 2 months ago)
- Language: JavaScript
- Homepage:
- Size: 63.5 KB
- Stars: 629
- Watchers: 16
- Forks: 40
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# hyperscript-helpers
![](https://travis-ci.org/ohanhi/hyperscript-helpers.svg)
Terse syntax for hyperscript.
> Less than 50 lines of code, taking your hyperscripting to the next level.
## What is it
**hyperscript-helpers** [elm-html](https://github.com/elm-lang/html/) inspired helpers for writing
[hyperscript](https://github.com/dominictarr/hyperscript) or [virtual-hyperscript](https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript).They work with `React.createElement`, but there is also a feature-rich hyperscript library for React:
[react-hyperscript](https://github.com/mlmorg/react-hyperscript).```javascript
// 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 functionsThis is super helpful, especially when using **hyperscript-helpers** with [Cycle.js](http://cycle.js.org/)!
See the supported `TAG_NAMES` here: [src/index.js](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:
```javascript
function attrs(id) {
return { draggable: "true", "data-id": id };
}
```How would we render these in plain hyperscript, JSX or with the helpers?
```javascript
// plain hyperscript
h('ul#bestest-menu', items.map( item =>
h('li#item-'+item.id, attrs(item.id), item.title))
);// JSX
- {item.title}
{items.map( item =>
)}
// 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:
```js
const h = require('hyperscript'); // or 'virtual-hyperscript'
const { div, span, h1 } =
require('hyperscript-helpers')(h); // ← Notice the (h)
```
With React
```js
// ✅ 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
```js
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:
```js
$ node
▸ const hh = require('hyperscript-helpers')(require('hyperscript'));
◂ undefined
▸ const { div, span, h1 } = hh;
◂ undefined
▸ span('😍').outerHTML
◂ '😍'
▸ h1({ 'data-id': 'headline-6.1.2' }, 'Structural Weaknesses').outerHTML
◂ '
Structural Weaknesses
'▸ div('#with-proper-id.wrapper', [ h1('Heading'), span('Spanner') ]).outerHTML
◂ '
Heading
Spanner
```
It's also natively supported to spell the helper function names with an uppercase first
letter, for example to avoid conflicts with existing variables or reserved
JavaScript keywords:
```js
▸ const { Span, Var } = hh;
◂ undefined
▸ Span('😍').outerHTML
◂ '😍'
▸ Var('x').outerHTML
◂ 'x'
```
Creating custom HTML tag names can be done with the `createTag` function:
```js
▸ const someFn = hh.createTag('otherTag');
◂ undefined
▸ someFn('bla').outerHTML
◂ 'bla'
```
## API
Because **hyperscript-helpers** are hyperscript-agnostic there is no "exact" API.
But, just to give you a direction of what should be possible:
```js
tagName(selector)
tagName(attrs)
tagName(children)
tagName(attrs, children)
tagName(selector, children)
tagName(selector, attrs, children)
```
Where
* `tagName` is a helper function named like the HTML element that it creates; **hyperscript-helpers** natively supports spelling the tag name with the first letter lowercase or uppercase.
* `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](https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript)) still applies.
For example, for multiple classes:
```js
// ... 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()` syntax and `` may be a string,
starting with `.` (period) or `#` (number sign), wrap the argument in `[]`.**
```js
// ✅ GOOD
filenames.map(filename => span([filename])); // README.md.gitignore
// ❌ BAD
filenames.map(span); // README.md
```
As most hyperscript is written by hand, we decided keep this convenient shortcut despite the [issue](https://github.com/ohanhi/hyperscript-helpers/issues/6#issuecomment-162989208).
### Logic in class names
If you need to apply logic rules for class generation,
we recommend using libraries like [classnames](https://github.com/JedWatson/classnames)
for making proper `{className: ...}` argument.
Not recommended:
```js
span(error ? ".error" : null); // ← may be a trap, because:
span(error ? ".error" : null, {}, []); // ← this one is wrong
```
## Tools
[html-to-hyperscript.paqmind.com](http://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:
```bash
# 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](http://jsverify.github.io/) library.
---
**hyperscript-helpers** is brought to you by [@ohanhi](https://twitter.com/ohanhi/).
License: MIT