Open arturi opened 8 years ago
Sometimes I have wished that all the h
modules were more interoperable. They all have slight differences that make them incompatible. bel, virtual-hyperscript, hyperscript, and react all have slight differences, though they do basically the same thing.
What does the compiled JSX code look like?
Compiled JSX with createElement
as pragma looks like this:
const el = createElement(
'h1',
null,
'Hi!'
)
And Bel, according to the docs, expects it to be:
var sameElement = createElement('h1', { className: 'heading' }, ['Hi!'])
More complex nested example:
const el = <div>
<h1>Hi, <strong>stranger</strong></h1>
<h2>Hello</h2>
</div>
Transpiled:
const el = createElement(
'div',
null,
createElement(
'h1',
null,
'Hi, ',
createElement(
'strong',
null,
'stranger'
)
),
createElement(
'h2',
null,
'Hello'
)
);
So their spec expects createElement(tag, attrs, ...children)
? I'm +1 on support their spec but low priority on my list.
So you’d want to support both or switch to their?
Support both if possible, not switch to theirs.
Hmmm, I feel the solution for bel / react compat would probably be to create a form of generic adapter that allows for arbitrary nodes to be passed into react, and just work™ - similar to how we've done it with cache-element/widget but for React
Does that make sense?
On Sun, Oct 23, 2016 at 5:25 AM nichoth notifications@github.com wrote:
Sometimes I have wished that all the h modules were more interoperable. They all have slight differences that make them incompatible. bel, virtual-hyperscript, hyperscript, and react all have slight differences, though they do basically the same thing.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/shama/bel/issues/56#issuecomment-255567353, or mute the thread https://github.com/notifications/unsubscribe-auth/ACWlel4YFRXU1W3zFpjh5QOPGtl_69-hks5q2tOZgaJpZM4KeCR3 .
seems it took a while for my emails to arrive 😅
On Tue, Oct 25, 2016 at 8:42 PM Yoshua Wuyts notifications@github.com wrote:
Hmmm, I feel the solution for bel / react compat would probably be to create a form of generic adapter that allows for arbitrary nodes to be passed into react, and just work™ - similar to how we've done it with cache-element/widget but for React
Does that make sense?
On Sun, Oct 23, 2016 at 5:25 AM nichoth notifications@github.com wrote:
Sometimes I have wished that all the h modules were more interoperable. They all have slight differences that make them incompatible. bel, virtual-hyperscript, hyperscript, and react all have slight differences, though they do basically the same thing.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/shama/bel/issues/56#issuecomment-255567353, or mute the thread < https://github.com/notifications/unsubscribe-auth/ACWlel4YFRXU1W3zFpjh5QOPGtl_69-hks5q2tOZgaJpZM4KeCR3
.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/shama/bel/issues/56#issuecomment-256133936, or mute the thread https://github.com/notifications/unsubscribe-auth/ACWlehKji7daqf9h4aF59xpz913D_jmhks5q3k16gaJpZM4KeCR3 .
One more thing related to this "spec" compliance is because to support components, not tags which means passing a functions as first argument not a string
var el = <Link foo="bar">Hello</Link>
is transpiled to
// should also support content to be a string, not an array
// because currently isn't possible
var el = createElement(Link, { foo: 'bar' }, ['Hello'])
kinda such thing
function arrayify (val) {
if (!val) return [];
if (Array.isArray(val)) return val;
return [val];
}
function isObject (val) {
return val && typeof val === 'object' && !Array.isArray(val)
}
function belCreateElement (tag, props, children) {
var el
children = arrayify(children)
props = isObject(props) ? props : {}
if (typeof tag === 'function') {
// not sure for the order
// but we should have `children` on `props` object
props.children = children || arrayify(props.children)
var _ele = tag(props, props.children)
// should remove `_ele._attributes.null.children`
return _ele
}
// not changed code below ...
}
seems to be working
examples
function Link (props) {
return belCreateElement('a', props, props.children.concat(' world!!'))
}
var el = belCreateElement(Link, { className: 'foo' }, 'Hello')
console.log(el.toString())
Ahref, not using props
argument directly (important to test both above and below cases!)
function Ahref ({ className, children }) {
return belCreateElement('a', { className }, children.concat(' world!!'))
}
var el = belCreateElement(Ahref, { className: 'foo' }, 'Hello')
console.log(el.toString())
MOAR
var hx = require('hyperx')(belCreateElement)
function Link (props) {
// JSX
// <a { ...props }>{ props.children.concat(' world...').join('') }</a>
return hx`<a ${ /* ...props */ } >${ props.children.concat(' world...').join('') }</a>`
}
// JSX
// var el = <Link className="foobar">Hello</Link>
var el = belCreateElement(Link, { className: 'foobar' }, 'Hello')
console.log(el.toString())
// expected
// => '<a class="foobar">Hello world...</a>'
I was wondering if its possible to use JSX instead of hyperx to create elements with Bel. I like to use Bel and Yo-yo, but sometimes its convenient to go JSX route, because then components could be re-used between Yo-yo/Choo and React projects.
I tried to set
jsx pragma
toh
and then use it like so:But children (
Hi
) never appear, and if you omitclass
, bel complaints:Cannot read property 'namespace' of null
. Got confused, probably missing something.