van icon indicating copy to clipboard operation
van copied to clipboard

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

Open cloudspeech opened this issue 2 years ago • 11 comments

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?

cloudspeech avatar May 25 '23 10:05 cloudspeech

Maybe you can try to combine it with htm.

laamfun avatar May 26 '23 02:05 laamfun

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)

olivmonnier avatar Jun 01 '23 20:06 olivmonnier

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
    }

efpage avatar Jun 03 '23 07:06 efpage

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

artydev avatar Jun 13 '23 16:06 artydev

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)

mgttt avatar Jun 27 '23 06:06 mgttt

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)

artydev avatar Jun 28 '23 09:06 artydev

image

jsx-van

I tried use jsx with vite.

Change jsxImportSource to the custom package.

It works fine.

cqh963852 avatar Aug 25 '23 17:08 cqh963852

@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.

coderbuzz avatar Sep 06 '23 04:09 coderbuzz

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

cqh963852 avatar Sep 06 '23 05:09 cqh963852

@coderbuzz You can check main/addons/van_jsx

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

tonivj5 avatar Nov 08 '23 10:11 tonivj5

@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.

cqh963852 avatar Nov 09 '23 04:11 cqh963852