UNPKG

5.56 kBMarkdownView Raw
1<a href="#about"><img alt="logo" width="1016" alt="2017-07-02 1 46 12" src="https://user-images.githubusercontent.com/8784712/27764289-6ffb8ab8-5ec8-11e7-8b30-9b59ecc1d47d.png"></a>
2
3## About
4
5This is not yet another minimalistic React implementation, the main use case is to create actual dom with a single function and JSX directly, but there're opt-in component lifecycle hooks.
6
7## Features
8
9- [x] Insanely small: 2kB minified
10- [x] One API: JSX is transformed to vNode, use `mount(vNode)` to get actual DOM.
11- [x] SVG support
12- [x] Protection from XSS injections
13- [x] Automatically joining classNames, styles
14
15## Install
16
17```bash
18yarn add dom-dom
19```
20
21CDN: [UNPKG](https://unpkg.com/dom-dom/dist/) | [jsDelivr](https://cdn.jsdelivr.net/npm/dom-dom/dist/)
22
23## Usage
24
25With a transpiler like `babel+babel-plugin-transform-react-jsx` or `typescript` or `buble`:
26
27```js
28/* @jsx h */
29import { h, mount } from 'dom-dom/tiny'
30
31// With only first arg
32const button = mount(<button>click me</button>)
33// button.outerHTML:
34// => '<button>click me</button>'
35
36// With second arg
37// replacce `#root` with created element
38mount(
39 <button>hello</button>,
40 document.getElementById('root')
41)
42```
43
44Note that while using CDN version you can access `d2.h` `d2.mount` instead.
45
46### className
47
48`className` can be `string` `Array` or `Object`:
49
50```js
51<div className="foo"></div>
52<div className={['foo', 'bar']}></div>
53<div className={{foo: false, [`bar-${index}`]: true}}></div>
54```
55
56You can also directly use `class` instead of react-specific `className` as you please:
57
58```js
59<div class="foo"></div>
60```
61
62### style
63
64`style` supports `string` and `Object`:
65
66```js
67<div style="color: red"></div>
68// both kebab-case and camelCase are supported here
69// default unit is `px`
70<div style={{ fontSize: 14, 'background-color': 'red' }}></div>
71```
72
73### innerHTML
74
75```js
76<div dangerouslySetInnerHTML={{__html: '<strong>hey</strong>'}}></div>
77```
78
79### Events
80
81React-like events are supports:
82
83```js
84<button onClick={handleClick}></button>
85```
86
87---
88
89> **WARNING:** If you only want a function to transform vNode to actual dom, please stop reading!!! Above features would be enough for your use case. Following features may not be what you want :D
90> To use full build you should `import { xxx } from 'dom-dom'` instead.
91
92<details><summary>Create your own React with <strong>dom-dom</strong></summary><br>
93
94```js
95// @jsx h
96
97import { h, mount, unmount } from 'dom-dom'
98
99class Component {
100 setState(state) {
101 if (typeof state === 'function') {
102 state = state(this.state)
103 }
104 for (const key in state) {
105 this.state[key] = state[key]
106 }
107 this.mount()
108 }
109
110 mount(root = this.$root) {
111 this.$root = mount(this, root)
112 return this.$root
113 }
114
115 destroy = () => {
116 unmount(this, this.$root)
117 }
118
119}
120
121class Counter extends Component {
122 state = { count: 0 }
123
124 handleClick = () => {
125 this.setState(prevState => ({
126 count: prevState.count + 1
127 }))
128 }
129
130 componentDidMount() {
131 console.log('app mounted!', this)
132 }
133
134 render() {
135 return (<div>
136 <button onClick={this.handleClick}>
137 clicked: {this.state.count} times
138 </button>
139 <button onClick={this.destroy}>destroy</button>
140 </div>)
141 }
142}
143
144const counter = new Counter()
145counter.mount(document.getElementById('root'))
146```
147
148[![Edit 9Q4n4XxAP](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/VyGn0DP5)
149</details><br>
150
151You can `mount` `unmount` a object or class instance which has a `render` method that returns `vNode`.
152
153```js
154import { h, mount } from 'dom-dom'
155
156const A = {
157 render() {
158 return <div>a</div>
159 }
160}
161
162const B = class {
163 render() {
164 return <div>{A}</div>
165 }
166}
167
168mount(new B, document.getElementById('root'))
169```
170
171Object and class instance with render function can also be one of your JSX children.
172
173This is designed for using lifecycle hooks, currently we have `componentDidMount` `componentWillMount` and `componentWillUnmount`.
174
175```js
176const App = {
177 componentDidMount() {
178 console.log('hi')
179 },
180 componentWillUnmount() {
181 console.log('bye')
182 },
183 render() {
184 return <div>hi</div>
185 }
186}
187
188const root = mount(App, document.getElementById('root'))
189//=> hi
190unmount(App, root)
191//=> bye
192```
193
194## Prior Art
195
196This project is heavily inspired by [preact](https://github.com/developit/preact) and [dom-chef](https://github.com/vadimdemedes/dom-chef).
197
198## Contributing
199
2001. Fork it!
2012. Create your feature branch: `git checkout -b my-new-feature`
2023. Commit your changes: `git commit -am 'Add some feature'`
2034. Push to the branch: `git push origin my-new-feature`
2045. Submit a pull request :D
205
206## Badges
207
208[![NPM version](https://img.shields.io/npm/v/dom-dom.svg?style=flat)](https://npmjs.com/package/dom-dom) [![NPM downloads](https://img.shields.io/npm/dm/dom-dom.svg?style=flat)](https://npmjs.com/package/dom-dom) [![CircleCI](https://circleci.com/gh/egoist/dom-dom/tree/master.svg?style=shield&circle-token=1b6201de2b133f5b995fe2730a24b497768d85c6)](https://circleci.com/gh/egoist/dom-dom/tree/master) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/egoist/donate)
209
210## Author
211
212**dom-dom** © [egoist](https://github.com/egoist), Released under the [MIT](./LICENSE) License.<br>
213Authored and maintained by egoist with help from contributors ([list](https://github.com/egoist/dom-dom/contributors)).
214
215> [egoistian.com](https://egoistian.com) · GitHub [@egoist](https://github.com/egoist) · Twitter [@rem_rin_rin](https://twitter.com/rem_rin_rin)