Skip to content

Make it possible to use JSX together with s-js computations

License

Notifications You must be signed in to change notification settings

MotorHeat/s-jsx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

s-jsx

This is yet another JavaScript view library that manages application state using S.js signals and creates real DOM nodes (similar to Surplus, Solid and others). It allows you to define your view in JavaScript using JSX syntax.

Intro

This project was inspired by S.js and Surplus. Surplus implements own compiler that transpiles JSX syntax to a plain JavaScript while this library implements the JSX Factory function that creates real DOM nodes and manages S-computations.

How it differs from Surplus?

  • You don't need a special compiler
  • You can use any existing JSX transpilers (Babel, TypeScript) that supports configuration of the jsxFactory function
  • JSX is not required for building applications with s-jsx. You can use "h" directly and without a compilation step (see below)

The Gist

Below is simple example of "Counter" app. Please note that you can use data signal directly <h2>{counter}</h2> if you just need to use it value. If you need some expression to be evaluated then you should wrap it with S-computation: <p>{S( () => "The counter value is " + counter())}</p>

Example

import { h } from 'jsx-s'
import S from 's-js'

const appState = {
    counter: S.data(0),
}

function CounterComponent({counter }) {
    return <div>        
        <h2>{counter}</h2>
        <p>{S( () => "The counter value is " + counter())}</p>
    </div>
}

function MainView(appState) {
    return <div>
        <CounterComponent counter={appState.counter}/>
        <button onclick={() => appState.counter(appState.counter() + 1)}>inc</button>
        <button onclick={() => appState.counter(appState.counter() - 1)}>dec</button>
    </div>
}

S.root( () => {
    document.body.appendChild(MainView(appState))
})

How to use it?

The above example assumes you are using a JavaScript compiler like Babel or TypeScript and a module bundler like Parcel, Webpack, etc. If you are using JSX, all you need to do is install the JSX transform plugin and add the pragma option to your .babelrc file.

{
  "plugins": [
      ["@babel/plugin-transform-react-jsx", {
        "pragma": "h", 
        "pragmaFrag": "h.fragment"
      }]
    ]  
}

S-JSX supports JSX fragments via h.fragment function. Fragments are implemented in Babel starting from version 7. Using fragments your views can return several DOM nodes:

function UserProfile({name, age, address}) {
  return <>
        <h1>{name}</h1>
        <h2>{age}</h2>
        <p>{address}</p>
    </>
}

JSX is a language syntax extension that lets you write HTML tags inside JavaScript files. We use compiler to transform it into "h" function calls under the hood. Note that JSX is not required for building applications with s-jsx. You can use "h" directly and without a compilation. This is the same example with counter but written with "h" function:

function CounterComponent({ counter }) {
    return h('div', {},
        h('h2', {}, counter),
        h('p', {}, S(() => "The counter value is " + counter()))
    )
}

function MainView(appState) {
    return h('div', {},
        h(CounterComponent, { counter: appState.counter }),
        h('button', { onclick: () => appState.counter(appState.counter() + 1) }, "inc"),
        h('button', { onclick: () => appState.counter(appState.counter() - 1) }, "dec")
    )
}

Does SVG supported?

Yes. If the tag name matches a known SVG element, s-jsx will create an SVG element instead of an HTML one. For the small set of tag names that belong to both -- <a>, <font>, <title>, <script> and <style> -- s-jsx creates an HTML element. Children of SVG elements are also SVG elements, unless their parent is the <foreignObject> element, in which case they are DOM elements again.

Why real DOM, why not virtual DOM?

Thar are million reasons to use real dom nodes and another million to use virtual dom. In short: because you don't need a virtual dom :) My personal oppinion is that the price you pay for using vDOM is much bigger than what you get from it. You can also read good explanation on this topic on Surplus page in FAQ section.

About

Make it possible to use JSX together with s-js computations

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published