-
Notifications
You must be signed in to change notification settings - Fork 18
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
JSX Fragment support #4
Comments
I'm aware that TypeScript has support. Not sure how you would like this to be implemented though. tsx-dom is currently always returning an HTMLElement. A Fragment is no HTMLElement. It would be an array of HTMLElements at best. If I change the return type to HTMLElement | HTMLElement[], you would always have to check the type of the returned value, which is a bit ugly. Possible alternativeI guess it would be an option to return an HTMLElement, which is flagged somehow. I.e. If you have the following code: const Greeting = () => <>hello <b>sportshead</b><>;
const element = <main><Greeting /></main>;
document.body.appendChild(element); You would see However if you where to use it like this: const element = <>hello <b>sportshead</b><>;
document.body.appendChild(element); You would see This would not be what users expected though, so this would have to be made very clear in the documentation. Of course, you could write a function to help with this issue: import { h, appendChild} from "tsx-dom";
const element = <>hello <b>sportshead</b><>;
appendChild(document.body, element); and tsxAppendChild could take care of this for you. But that also adds some complexity to the usage and people might forget. |
How about document fragments? https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment |
The issue remains. The jsx syntax can only return one specified type. That is currently HTMLElement. DocumentFragment does not inherit from HTMLElement. Both inherit from Node, but returning Node for all jsx snippets would mean, that for the most common case of HTMLElement, you'd have to cast it. This is a limitation of the jsx syntax. When using functions, typescript could infer the return type by looking at the parameter types. But the jsx syntax currently does not support this. That is the reason why this returns HTMLElement and not HTMLInputElement: const in = <input />; So if you want the input specific values, you need to cast: const in = <input /> as HTMLInputElement; Imagine having to do that for every plain HTMLElement. |
How do the other react libraries do it? It seems like the typings for their Fragments work |
After looking through some code, it looks like all the other libs use It seems though that |
This looks interesting: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver Perhaps start a observer on the first time that a fragment is created? Then the callback for the observer can remove |
The other libs have their own render methods (i.e. you don't do appendChild, but their method does it for you. prototype polution is an anti-pattern and I won't use it. MutationObserver might break some of the use-cases, where no real browser is used. |
Then what do you suggest? |
Well, either wait for typescript to support this scenario or create a hacky solution. tsx-dom is not a virtual-dom library like react, preact, etc. So it does not manage those kinds of rendering issues for you. It's simply here to make it easy to create elements. If you're only looking to create a
With:
Then everywhere you use fragments, import that function into scope. It's not the same though, as your dom will look different and styling may be affected. That's mainly why I'm not gonna build that into tsx-dom by default. If you find another solution, which does not break existing code, I'm open to take a good look. But right now, I'm not aware of anything. |
What about using https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment to create a very simple implementation? Just noticed this was already discussed my bad. |
Typescript has JSX fragment support (microsoft/TypeScript#38720), but tsx-dom hasn't implemented it yet
Edit: I've found a temporary workaround:Edit 2: The temporary workaround does not work
The text was updated successfully, but these errors were encountered: