-
Notifications
You must be signed in to change notification settings - Fork 178
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
Custom JSX/TSX components #245
Comments
Documentation is indeed very laconic currently. It's both lagging behind the code and fails to explain some of the core concepts. Here is a JSX working test case for building a custom Nuemark extension: https://github.com/nuejs/nue/blob/master/packages/nuemark/test/nuemark.test.js#L430 That's all there is now with regards to extension. Hope that helps. The idea is to finish the core pieces first and launch a v1.0, before moving into extensions and integrations. Nue is still an early beta. |
Thank you very much for your response and advice @tipiirai! At the beginning I would like to sorry for my late response and share my results so maybe it can help also other developers to understand better the problem and solution. Zag integration resultsLet's forget about Zag. I was able to implement working integration with a simple Number Input component by myself, but I was not happy with the code. One of the biggest reason is the lack of the spread properties feature available in JSX/TSX. I had to implement my own solution for that. Another reason is that this library has its own logic implementation for each component based on the state machines. This is another custom abstraction layer and the library itself is also very much tightly coupled to the React, Solid, Vue and heavily relies on the concepts from these frameworks. Because the main reason of the Nue framework is to be closer to the web standards I decided to search something else and I found Shoelace which is a collection of UI components build on web components standard. Thanks to this the components implementation is fully framework agnostic. Library looks mature and I am going to test these components together with Nue and built SPA with forms. It should eliminate any need to create custom integrations and so on. Custom JSX/TSX componentsComing back now to the original problem. I decided to investigate further the custom components problem inspired by the Custom components section and especially TSX components section. My main idea was to create custom TSX components and render them on the client side in the browser in my SPA. In my previous attempts, I didn't know how to properly import Nuemark API. The reason was that I didn't read carefully Unbundled distribution section which says:
So I decided to bundle the Nuemark API. Unfortunately the Bundled distribution section was not quite clear for me. I couldn't understand how the // *.nue file
import { nuemarkdown } from "nuemark"; nothing happened... After transpiling the project files, the // index.ts
export { nuemarkdown } from "nuemark"; The Nuemark API has been finally inlined into generated The next step was to create TSX components that I could render in my SPA. According to the TSX components section I added following dependencies to the project folder:
and created TSX components library: // components.tsx
// import of the React SSR (server-side rendering)
import { renderToString } from "react-dom/server";
// first custom tag
function MyTag(props: { message: string }) {
return <h1 style={{ color: "red" }}>{props.message}</h1>;
}
// second custom tag
function MyTag2(props: { message: string }) {
return <h1 style={{ color: "blue" }}>{props.message}</h1>;
}
const components = { MyTag, MyTag2 };
// Make lib compatible with Nuemark
export const tsx_lib = Object.keys(components).map((name) => {
return {
name,
render: function (data, lib) {
return renderToString(components[name](data, lib));
},
};
}); After debugging your code I already knew that Nue CLI treats
After that the // tsx-component.nue
<script>
import { nuemarkdown } from './index.js'
import { tsx_lib } from './components.js'
</script>
<div @name="tsx-component">
<script>
mounted({ name, data }) {
const html = nuemarkdown(`[${name}]`, {
data,
lib: tsx_lib,
});
/**
* The this.mountChild() method unfortunately is not documented enough
* so I had to use this ugly solution:
*/
this.$el.innerHTML = html
}
</script>
</div> All I had to do was consume my amazing custom Nue component in SPA: // home-view.nue
<section @name="home-view">
<script>
tag = { message: "My first custom tag!" }
tag2 = { message: "My second custom tag!" }
</script>
<h1>Hello, World!</h1>
<tsx-component name="my-tag" :data="tag" />
<tsx-component name="my-tag2" :data="tag2" />
</section> The results are visible on the screenshot 🎉 ConclusionsI am sorry for such a long answer, but I wanted to share my solution with you @tipiirai and other developers. It might help to shed some light on the problems I faced during implementation of the custom JSX/TSX components and possible solutions. This PoC opens possibility to implement integrations with different frameworks, however I have no idea if your intention was to use Nuemark API in a such way on the client-side components. I have the impression that you prepared this API for server-side components, despite the fact that there is no mention of them in the documentation. I am fully aware of that the idea is to finish the core pieces first and launch a v1.0, before moving into extensions and integrations, but just wanted to check if I implemented custom TSX components as intended or maybe you had different vision behind it. Regards |
Hello,
I really appreciate your vision @tipiirai to create finally framework that works closely with the web standards, however in many cases your documentation is still very laconic. Looks like an area that needs improvement 😄
Currently I am interested in integration with some headless UI library that works for vanilla JS and not only for React. I found Zag which claims is a framework agnostic library for implementing even complex UI components. Unfortunately looks like they do not have any dedicated tools for integration with pure JavaScript implementation. Looking through your documentation I spotted this section Custom components and more importantly this section TSX components that shows how to create custom TSX components which looks really promising. I have been trying to create simple component, but looks like I do not understand something or violate some core concepts of your framework.
My main idea is to create a custom component that integrates with the Zag framework according to their docs Number Input (React example):
As visible above all properties are passed to the HTML elements with the spread operator syntax which works in JSX.
In my case I wasn't even able to create the simplest custom JSX/TSX component:
I couldn't even import the package correctly to make it work like below:
I was trying to run this code in the browser context by implementing
library.js
file and then use custom component in my reactive island. I have a feeling that you had another idea behind this API.Bunch of questions below:
I am aware of your development focus and roadmap, but I really would like to start building product with your framework. Any details and help from your side will be very appreciated!
Regards
The text was updated successfully, but these errors were encountered: