Skip to content

egoist/dom-dom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo

About

This is not yet another minimalistic React implementation, the primary use case is to create actual dom with a single function and JSX directly, but there're opt-in component lifecycle hooks.

This lib does not accept pull requests for new features since the primary use case (get actual DOM from JSX) is already set for good.

Features

  • Insanely small: 2kB minified
  • One API: JSX is transformed to vNode, use mount(vNode) to get actual DOM.
  • SVG support
  • Protection from XSS injections
  • Automatically joining classNames, styles

Install

yarn add dom-dom

CDN: UNPKG | jsDelivr

Usage

With a transpiler like babel+babel-plugin-transform-react-jsx or typescript or buble:

/* @jsx h */
import { h, mount } from 'dom-dom/tiny'

// With only first arg
const button = mount(<button>click me</button>)
// button.outerHTML:
// => '<button>click me</button>'

// With second arg
// replacce `#root` with created element
mount(
  <button>hello</button>, 
  document.getElementById('root')
)

Note that while using CDN version you can access d2.h d2.mount instead.

className

className can be string Array or Object:

<div className="foo"></div>
<div className={['foo', 'bar']}></div>
<div className={{foo: false, [`bar-${index}`]: true}}></div>

You can also directly use class instead of react-specific className as you please:

<div class="foo"></div>

style

style supports string and Object:

<div style="color: red"></div>
// both kebab-case and camelCase are supported here
// default unit is `px`
<div style={{ fontSize: 14, 'background-color': 'red' }}></div>

innerHTML

<div dangerouslySetInnerHTML={{__html: '<strong>hey</strong>'}}></div>

Events

React-like events are supports:

<button onClick={handleClick}></button>

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 To use full build you should import { xxx } from 'dom-dom' instead.

Create your own React with dom-dom
// @jsx h

import { h, mount, unmount } from 'dom-dom'

class Component {
  setState(state) {
    if (typeof state === 'function') {
      state = state(this.state)
    }
    for (const key in state) {
      this.state[key] = state[key]
    }
    this.mount()
  }

  mount(root = this.$root) {
    this.$root = mount(this, root)
    return this.$root
  }
  
  destroy = () => {
    unmount(this, this.$root)
  }

}

class Counter extends Component {
  state = { count: 0 }

  handleClick = () => {
    this.setState(prevState => ({
      count: prevState.count + 1
    }))
  }
  
  componentDidMount() {
    console.log('app mounted!', this)
  }
  
  render() {
    return (<div>
      <button onClick={this.handleClick}>
        clicked: {this.state.count} times
      </button>
      <button onClick={this.destroy}>destroy</button>
    </div>)
  }
}

const counter = new Counter()
counter.mount(document.getElementById('root'))

Edit 9Q4n4XxAP


You can mount unmount a object or class instance which has a render method that returns vNode.

import { h, mount } from 'dom-dom'

const A = {
  render() {
    return <div>a</div>
  }
}

const B = class {
  render() {
    return <div>{A}</div>
  }
}

mount(new B, document.getElementById('root'))

Object and class instance with render function can also be one of your JSX children.

This is designed for using lifecycle hooks, currently we have componentDidMount componentWillMount and componentWillUnmount.

const App = {
  componentDidMount() {
    console.log('hi')
  },
  componentWillUnmount() {
    console.log('bye')
  },
  render() {
    return <div>hi</div>
  }
}

const root = mount(App, document.getElementById('root'))
//=> hi
unmount(App, root)
//=> bye

Prior Art

This project is heavily inspired by preact and dom-chef.

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Badges

NPM version NPM downloads CircleCI donate

Author

dom-dom © egoist, Released under the MIT License.
Authored and maintained by egoist with help from contributors (list).

egoistian.com · GitHub @egoist · Twitter @_egoistlily

About

JSX to actual DOM.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published