vanjs-org / van

🍦 VanJS: World's smallest reactive UI framework. Incredibly Powerful, Insanely Small - Everyone can build a useful UI app in an hour.
https://vanjs.org
MIT License
3.76k stars 86 forks source link

Allow lit-html-like templates as worthy, yet build-free JSX replacement #11

Open cloudspeech opened 1 year ago

cloudspeech commented 1 year ago

Discussed in https://github.com/vanjs-org/van/discussions/10

Originally posted by **cloudspeech** May 25, 2023 VanJS' HTML-markup-as-nested-JS-function-calls approach to templating is going to be a hard sell to the wider community, especially people that have seen React. They just want something like JSX. Lit-html has a very nice syntax that comes very close to JSX, yet only uses browser-native means. See https://lit.dev/docs/templates/overview/. I humbly suggest to not reinvent the wheel but provide an **add-on** to VanJS that supports unchanged lit-html template syntax (properties, attributes, events at minimum, perhaps also ref). This way the vanJS base size can be kept minimal for purists. I expect the add-on's size to likewise be very small (using DOMParser). What do you think?
laamfun commented 1 year ago

Maybe you can try to combine it with htm.

olivmonnier commented 1 year ago

If you're interest by an example with htm:

import htm from 'https://unpkg.com/htm?module'
import van from "./van-0.11.10.min.js"

function h(type, props, ...children) {
  const tag = van.tags[type]
  if (props) return tag(props, ...children)
  return tag(...children)
}

const html = htm.bind(h)

const counter = van.state(0)

const app = html`<div>
  ❤️ ${counter}
  <button onclick="${() => ++counter.val}">👍</button>
  <button onclick="${() => --counter.val}">👎</button>
</div>`

document.body.appendChild(app)
efpage commented 1 year ago

You can use this approach to use template literals, which is very fast too:

    // create element from innerHTML
    function html(s) {
      let d = div()
      d.innerHTML = s
      return d.firstChild
    }
artydev commented 1 year ago

Thank you olivmonnier, This could be attractive for many 'react like' users :-)

mgttt commented 1 year ago

You can use this approach to use template literals, which is very fast too:

    // create element from innerHTML
    function html(s) {
      let d = div()
      d.innerHTML = s
      return d.firstChild
    }

evolve to

var s2dom=(s,d=div())=>(d.innerHTML=s,d.firstChild)
artydev commented 1 year ago

Here is what 'htm' allows to do VanHTM :

import htm from 'https://unpkg.com/htm?module'
import van from "./van.js"

function h(type, props, ...children) {
  const tag = van.tags[type]
  if (props) return tag(props, ...children)
  return tag(...children)
}

const html = htm.bind(h)

const counter = van.state(0)

function Incer() {
  return html`<button onclick="${() => ++counter.val}">👍</button>`
}

const app = html`
  <div>
    ❤️ ${counter}
    ${Incer()}
    <button onclick="${() => --counter.val}">👎</button>
  </div>`

document.body.appendChild(app)
cqh963852 commented 1 year ago

image

jsx-van

I tried use jsx with vite.

Change jsxImportSource to the custom package.

It works fine.

coderbuzz commented 12 months ago

@cqh963852 Can you share the project template?

image

jsx-van

I tried use jsx with vite.

Change jsxImportSource to the custom package.

It works fine.

cqh963852 commented 12 months ago

@coderbuzz You can check https://github.com/vanjs-org/van/tree/main/addons/van_jsx

tonivj5 commented 9 months ago

@coderbuzz You can check main/addons/van_jsx

wooow @cqh963852, that's amazing! Could I ask you how you generate a distributable build?

cqh963852 commented 9 months ago

@coderbuzz You can check main/addons/van_jsx

wooow @cqh963852, that's amazing! Could I ask you how you generate a distributable build?

@tonivj5

If you mean a npm package. You can check https://www.npmjs.com/package/vanjs-jsx.