Description
Initial checklist
- I read the support docs
- I read the contributing guide
- I agree to follow the code of conduct
- I searched issues and couldn’t find anything (or linked relevant results below)
Problem
This is arguably outside of the scope of the reason that hastscript
exists, and I fully acknowledge that. However, I do believe it would be a value add.
I'm working on jsx-email and one of my goals to have cross-framework compatibility with the components it exports - effectively untethering from requiring react as a dependency. One of the bananas scenarios there is that users are running the components it exports in several different environments, one of which is Storybook. Since it has a few components that perform async operations, it needs to use <Suspense/>
. Similar to Fragment
in react, this is a symbol with children, with the added fallback
prop.
I put together a little test script to see what would happen should I inject react-specific JSX into the generic JSX supported by hastscript
:
/** @jsxImportSource hastscript */
import { h } from 'hastscript';
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
import { Suspense } from 'react';
import * as reactRuntime from 'react/jsx-runtime';
const component = (
<>
<Suspense fallback={<div>waiting</div>}>
<div class="foo" id="some-id"></div>
</Suspense>
</>
);
console.log(component);
console.log();
console.log(toJsxRuntime(component, reactRuntime as any));
I was pleasantly surprised to find that it handled the Suspense
"component" there quite gracefully by simply discarding it:
{
type: 'root',
children: [
{
type: 'element',
tagName: 'div',
properties: [Object],
children: [Array]
}
]
}
But that result (in this potentially erroneous context) discards the Suspense
component altogether. Using hast-util-to-jsx-runtime
to convert it to React predictably results in the missing Suspense
component.
To that end, I'd love to see support for exotic components (which may just be symbols that have props) in hastscript. While probably not the intended use it would open up some new possibilities for this lib's use.
Solution
I'm not quite sure how this would be accomplished, and since I'm in an evaluation phase of possible broader solutions for my use-case, I haven't done a deep dive on the code here to suggest a path forward. I would love to get your initial thoughts on how this might be supported.
Alternatives
I've been unsuccessfully working on a generic renderer that can handle JSX formats of React, Preact, and SolidJS. The variances are significant and I haven't been able to accommodate them all - and that doesn't even go into the type incompatibilities between them. Coupled with the fact that I'd have to race to keep up with any changes in each framework, it seems like a losing path over time. I was excited to find this and hast-util-to-jsx-runtime
because it opens a new path where I can write my components in a standard which can then be converted to the appropriate format for each.