-
-
Notifications
You must be signed in to change notification settings - Fork 3
Add support using x
as a JSX pragma
#4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
This PR tests that `xastscript` can be used as the pragma for JSX with bublé and babel. Code-wise, this adds support for using `x` to generate root nodes. This is done by omitting the tag name (like so: `x()`, `x(null, 'child')`). Previously, omitting a `name` resulted in an exception. Another aspect of supporting JSX is supporting fragments as children. As fragments yield root nodes, we unravel them and use only their children. While this could be seen a change, xast prohibits roots occurring in nodes, so the unraveling instead fixes what would otherwise be a broken tree. Related to: GH-3.
This happened really fast. I think the idea of using What about adding support for adding actual functional components, so these can be used to generated non-element nodes. I.e. the root node: Implementation: function Root(props, ...children) {
return { type: 'root', children };
} Usage: /** @jsx h */
const { Root, x } = require('hastscript')
module.exports = (
<Root>
<foo>
<bar />
</foo>
</Root>
) This way more types of nodes can be defined as well, i.e.: /** @jsx h */
const { Comment, Doctype, Instruction, Root, x } = require('hastscript')
module.exports = (
<Root>
<Doctype name="" public="" system="" />
<Instruction name="" />
<Comment>Hello</Comment>
<foo>
<bar />
</foo>
</Root>
) The implementation in if (typeof tag === 'function') {
return tag(attributes, ...children)
} I think the most common use case for fragments is to do something like this: /** @jsx h */
const { Comment, Fragment, Root, x } = require('hastscript')
module.exports = (
<Root>
<Doctype name="" public="" system="" />
<Instruction name="" />
<people>
{people.map(person => (
<>
<name>{person.name}</name>
<age>{person.age}</age>
</>
))}
</people>
</Root>
) |
Yes, sorry!
Would any other symbol work?
The changes in the API introduced in this PR are a two part act: yes, roots can be made, but roots are also unraveled. So fragments in your last example also work: https://github.com/syntax-tree/xastscript/pull/4/files#diff-f5b3878f8f75d9cd3df39252cba892d4689833207338622ddb3ae7ecb2c6ef17R106
This to me sounds like a different feature that could be added on top. Or not. As JSX handled Capitalized and members.of.objects as identifiers instead of strings, they can all be used already: https://github.com/syntax-tree/xastscript/pull/4/files#diff-f5b3878f8f75d9cd3df39252cba892d4689833207338622ddb3ae7ecb2c6ef17R44, if they resolve to valid values for What is the benefit of adding “components”?
Those nodes aren’t used a lot, is this an actual need? React also doesn’t support comments. Nodes can also already be passed as children: https://github.com/syntax-tree/xastscript#jsx. If we’d just want to add other nodes, we could also support “templates”: x.Comment = {type: 'comment'}
x.Doctype = {type: 'doctype'}
x.Fragment = undefined
x.Root = undefined
function x(name, attributes) {
var node =
name == null
? {type: 'root', children: []}
: typeof name === 'object'
? Object.assign({}, name)
: {type: 'element', name: name, attributes: {}, children: []}
// ... and handle `attributes` as direct props instead of `node.attributes`
}
const { Comment, Doctype, Fragment, Root, x } = require('xastscript')
module.exports = (
<Root>
<Doctype name="" public="" system="" />
<Instruction name="" />
<people>
{
// ...
}
</people>
</Root>
) |
Apparently the React TypeScript definitions don’t match the React code here. I think your solution below to define I do love the idea fragments don’t need to be imported. :)
I didn’t know that. That’s awesome! Never mind any of my objections then. :)
The main reason for this was to define It still may be useful to support components, so the XML tree can be composed using JSX syntax.
This was basically a continuation on the thought Fragments must be functions. |
and:
That seems weird? I thought this was pretty common? Such as: https://stackoverflow.com/a/33471928
Yeah, I wonder how that’d work. If it would be useful. |
This change tests that `hastscript` can be used as the pragma for JSX with bublé and babel. Code-wise, this adds support for using `h` to generate root nodes. This is done by omitting the tag name (like so: `h()`, `h(null, 'child')`). Previously, omitting a `name` resulted in the default element to be created (`div` for `h`, `g` for `s`). This change thus is a breaking change. The old behavior is still available when passing an empty string: `h('')`. Another aspect of supporting JSX is supporting fragments as children. As fragments yield root nodes, we unravel them and use only their children. While this could be seen a change, hast prohibits roots occurring in nodes, so the unraveling instead fixes what would otherwise be a broken tree. Related to: syntax-tree/xastscript#3. Related to: syntax-tree/xastscript#4.
This PR tests that
xastscript
can be used as the pragma for JSX with bubléand babel.
Code-wise, this adds support for using
x
to generate root nodes.This is done by omitting the tag name (like so:
x()
,x(null, 'child')
).Previously, omitting a
name
resulted in an exception.Another aspect of supporting JSX is supporting fragments as children.
As fragments yield root nodes, we unravel them and use only their children.
While this could be seen a change, xast prohibits roots occurring in nodes,
so the unraveling instead fixes what would otherwise be a broken tree.
Related to: GH-3.
/cc @remcohaszing, @ChristianMurphy