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
- Host: GitHub
- URL: https://github.com/vadimdemedes/dom-chef
- Owner: vadimdemedes
- License: mit
- Created: 2017-06-30T16:39:14.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-09-03T21:03:20.000Z (8 months ago)
- Last Synced: 2025-03-10T10:46:42.370Z (2 months ago)
- Language: TypeScript
- Size: 388 KB
- Stars: 518
- Watchers: 11
- Forks: 12
- Open Issues: 7
-
Metadata Files:
- Readme: readme.md
- Funding: .github/funding.yml
- License: license
Awesome Lists containing this project
- awesome-jsx - dom-chef
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)