van
van copied to clipboard
Allow lit-html-like templates as worthy, yet build-free JSX replacement
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?
Maybe you can try to combine it with htm.
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)
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
}
Thank you olivmonnier, This could be attractive for many 'react like' users :-)
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)
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)
I tried use jsx with vite.
Change jsxImportSource to the custom package.
It works fine.
@cqh963852 Can you share the project template?
I tried use jsx with vite.
Change jsxImportSource to the custom package.
It works fine.
@coderbuzz You can check https://github.com/vanjs-org/van/tree/main/addons/van_jsx
@coderbuzz You can check
main/addons/van_jsx
wooow @cqh963852, that's amazing! Could I ask you how you generate a distributable build?
@coderbuzz You can check
main/addons/van_jsxwooow @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.

