An open API service indexing awesome lists of open source software.

https://github.com/vadimdemedes/dom-chef

🍔 Build DOM elements using JSX automatically
https://github.com/vadimdemedes/dom-chef

Last synced: 18 days ago
JSON representation

🍔 Build DOM elements using JSX automatically

Awesome Lists containing this project

README

        











> Build regular DOM elements using JSX

With `dom-chef`, you can use Babel or TypeScript to transform [JSX](https://reactjs.org/docs/introducing-jsx.html) into plain old DOM elements, without using the unsafe `innerHTML` or clumsy `document.createElement` calls.

It supports everything you expect from JSX, including:

- [SVG elements](#render-svg)
- [Event listeners](#inline-event-listeners)
- [Inline CSS](#inline-styles)
- [Nested elements](#nested-elements)
- [Function elements](#use-functions)

If something isn't supported (or doesn't work as well as it does in React) please open an issue!

## Install

```
$ npm install dom-chef
```

## Usage

Make sure to use a JSX transpiler (e.g. [Babel](#babel), [TypeScript compiler](#typescript-compiler), [esbuild](https://esbuild.github.io/content-types/#using-jsx-without-react), you only need one of them).

```jsx
import {h} from 'dom-chef';

const handleClick = e => {
// was clicked
};

const el = (



Download


);

document.body.appendChild(el);
```

### Babel

`pragma` and `pragmaFrag` must be configured this way. More information on [Babel’s documentation](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx.html#pragma).

```js
// babel.config.js

const plugins = [
[
'@babel/plugin-transform-react-jsx',
{
pragma: 'h',
pragmaFrag: 'DocumentFragment',
},
],
];

// ...
```

### TypeScript compiler

`jsxFactory` and `jsxFragmentFactory` must be configured this way. More information on [TypeScripts’s documentation](https://www.typescriptlang.org/tsconfig#jsxFactory).

```jsonc
// tsconfig.json

{
"compilerOptions": {
"jsxFactory": "h",
"jsxFragmentFactory": "DocumentFragment"
}
}
```

### Alternative usage

You can avoid configuring your JSX compiler by just letting it default to `React` and exporting the `React` object:

```js
import React from 'dom-chef';
```

## Recipes

### Set classes

```jsx
const el = Text;

// or use `className` alias
const el = Text;
```

### Inline styles

```jsx
const el =

;
```

### Inline event listeners

```jsx
const handleClick = e => {
// was clicked
};

const el = Text;
```

This is equivalent to: `span.addEventListener('click', handleClick)`

### Nested elements

```jsx
const title =

Hello World

;
const body =

Post body

;

const post = (


{title}
{body}

);
```

### Set innerHTML

```jsx
const dangerousHTML = 'alert();';

const wannaCry =

;
```

### Render SVG

**Note**: Due to the way `dom-chef` works, tags ``, ``, ``, ``, `` and `<video>` aren't supported inside `<svg>` tag.

```jsx
const el = (
<svg width={400} height={400}>
<text x={100} y={100}>
Wow
</text>
</svg>
);
```

### Use functions

If element names start with an uppercase letter, `dom-chef` will consider them as element-returning functions:

```jsx
function Title() {
const title = document.createElement('h1');
title.classList.add('Heading');
return title;
}

const el = <Title className="red">La Divina Commedia</Title>;
// <h1 class="Heading red">La Divina Commedia</h1>
```

This makes JSX also a great way to apply multiple attributes and content at once:

```jsx
const BaseIcon = () => document.querySelector('svg.icon').cloneNode(true);

document.body.append(
<BaseIcon width="16" title="Starry Day" className="margin-0" />
);
```

To improve compatibility with React components, `dom-chef` will pass the function's `defaultProps` property to itself (if present). Note that specifying attributes won't override those defaults, but instead set them on the resulting element:

```jsx
function AlertIcon(props) {
return <svg width={props.size} className={props.className} />
}

AlertIcon.defaultProps = {
className: 'icon icon-alert'
size: 16,
}

const el = <AlertIcon className="margin-0" size={32} />;
// <svg width="16" class="icon icon-alert margin-0" size="32" />
```

## License

MIT © [Vadim Demedes](https://github.com/vadimdemedes)