1.1.3 • Published 3 years ago

@turtlemay/jsx-dom v1.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

@turtlemay/jsx-dom

This minimal, zero-dependency JSX factory allows you to use React-like design patterns with web components and other native DOM elements. Most JSX patterns and special attributes are supported.

npm (scoped)

Example

import * as React from '@turtlemay/jsx-dom'

// Define a custom element type.
class MyCustomElement extends HTMLElement {
  connectedCallback() {
    this.innerHTML = ''
    this.appendChild(<p>hello {MyCustomElement.name}</p>)
  }
}

// Register our custom element.
customElements.define(`x-${MyCustomElement.name.toLowerCase()}`, MyCustomElement)

// Use the custom element type like a React component.
document.body.appendChild(
  <MyCustomElement
    // Use the ref callback to save your element reference.
    ref={v => this._myElemRef = v}

    // Props matching a native property name will be assigned to that property.
    onclick={e => {}}
    // Camel cased event callbacks are also assigned via the corresponding native property.
    onMouseDown={e => {}}

    // Style objects are also supported.
    style={{ border: '1px solid red' }}

    // Anything else becomes a native attribute.
    my-string-attrib="foo"
    my-number-attrib={0}
    my-boolean-attrib={true}
    // Objects become json-stringified.
    my-object-attrib={{ foo: "bar" }} />
)

Installation

npm install @turtlemay/jsx-dom

Usage

Simply import the module into your JSX files using the React namespace:

import * as React from '@turtlemay/jsx-dom'

And write some JSX:

const attribs = {
  foo: 'foo',
  bar: 'bar',
}
const div = <div {...attribs} baz="baz" qux="qux" />

JSX elements become native DOM elements:

console.assert(
  <div /> instanceof HTMLDivElement
)

And fragments become document fragments:

console.assert(
  <></> instanceof DocumentFragment
)

Optional Configuration

With TypeScript you can use a namespace other than React by setting your tsconfig.json:

{
  "jsx": "react",
  "reactNamespace": "JSXFactory"
}
import * as JSXFactory from '@turtlemay/jsx-dom'

const div = <div />

Tips

Use a decorator for easy component registration:

// Decorator with optional tag name to define custom elements.
function registerComponent(tagName) {
  return type => {
    if (!tagName) tagName = 'x-' + type.name.toLowerCase()
    if (customElements.get(tagName)) return
    customElements.define(tagName, type)
  }
}

// Decorate your components.
@registerComponent()
class MyComponent extends HTMLElement {}

For passing non-serializable props, use an initializer:

@registerComponent()
class MyComponent extends HTMLElement {
  init(myArg) {
    // Use your arguments to perform initialization.
    return this
  }
}

document.body.appendChild(
  MyComponent.prototype.init.call(
    <MyComponent my-serializable-prop="" />,
    { myNonSerializableProp: Symbol() }
  )
)
1.1.0

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.0.0

5 years ago

0.5.4

7 years ago

0.5.3

7 years ago

0.5.2

7 years ago

0.5.1

7 years ago

0.5.0

7 years ago

0.4.0

7 years ago

0.3.4

7 years ago

0.3.3

7 years ago

0.3.2

7 years ago

0.3.1

7 years ago

0.3.0

7 years ago

0.2.2

7 years ago

0.2.1

7 years ago

0.2.0

7 years ago

0.1.0

7 years ago

0.0.1

8 years ago