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
PoC: feat(jsx): Introduce event handler for IntrinsicElements. #1780
base: main
Are you sure you want to change the base?
Conversation
The general usage is as follows const app = new Hono()
app.get(
'/page/*',
jsxRenderer(({ children }) => {
let finalize = () => {}
const finalizePromise = new Promise<void>((resolve) => (finalize = resolve))
return jsxNode(
<html>
<head>
<style />
</head>
<body>
<header>Menu</header>
<div>{children}</div>
</body>
</html>
)
.on('renderToString', ({ node }) => {
// gather all class name data
})
.on('renderToString.style', ({ setContent }) => {
setContent(finalizePromise.then(() => 'generated css'))
})
.on('afterRenderToString.html', finalize)
})
)
app.get('/page/about', (c) => {
return c.render(<h1 class='fs12'>About me!</h1>)
}) MoreIt would be great if the following statements could be eliminated let finalize = () => {}
const finalizePromise = new Promise<void>((resolve) => (finalize = resolve)) |
Hi @usualoma, This is really interesting! But, I can't imagine use cases for me right now though there are many cases. I'll give it some thought. |
I think this is the most simplest use case, isn't it? app.get('/', (c) => {
const node = jsxNode(
<htm>
<body>
<div>Hello</div>
<script>console.log('Hello');</script>
</body>
</htm>
).on('renderToString.script', ({ setContent, node }) => {
setContent(
new Promise((resolve) => {
resolve(`<script>${node.children[0]}</script>`)
})
)
})
return c.html(node.toString())
}) |
@yusukebe Thanks. Yes, that is a simple example! app.get('/', (c) => {
const node = jsxNode(
<html>
<body>
<div>Hello</div>
<script>console.log('Hello');</script>
</body>
</html>
).on('renderToString.script', ({ setContent, node }) =>
setContent(`<script>${node.children[0]}</script>`)
)
return c.html(node.toString())
}) It's not cool that |
2e92927 eliminates the need to write const app = new Hono()
app.get('/', (c) => {
const node = jsxNode(
<html>
<body>
<div>Hello</div>
<script>console.log('Hello');</script>
</body>
</html>
).on('renderToString.script', ({ setContent, node }) =>
setContent(`<script>${node.children[0]}</script>`)
)
return c.html(node)
}) |
However, while I think this is an exciting feature, I have not found a "strong motivation or use case that requires implementation" at this time, so I guess it is a good idea to think it through without rushing to merge. |
I agree. I think this seems to be a "low-level" API for users, so we should explore more applicational use cases for it. |
What about a feature like this, which would greatly expand the possibilities of JSX?
What can we do?
The following example shows the writing of a style element using MasterCSS(@2.0.0-beta) and the embedding of the transpiled TypeScript with esbuild.
With the following script,
The following results can be obtained
Will performance be degraded?
Performance was not degraded in the existing use cases that did not use
.on()
.When to use
jsxNode()
?(<App />)
returns aJSX.Element
, butJSX.Element
is defined asHtmlEscapedString | Promise<HtmlEscapedString>
, which can be converted to aJSXNode
usingas unknown as JSXNode
ortemplate instanceof JSXNode
, which is a bit annoying, so we use it to convert this to aJSXNode
type.Author should do the followings, if applicable
yarn denoify
to generate files for Deno