From 5993b6106774459ee88bcbef3bed9641b5ce772f Mon Sep 17 00:00:00 2001
From: Taku Amano
Date: Sun, 12 Jun 2022 08:20:31 +0900
Subject: [PATCH] feat(middleware/jsx): We need Fragment. (#310)
---
src/middleware/jsx/index.test.tsx | 28 +++++++++++++++++++++++++---
src/middleware/jsx/index.ts | 14 +++++++++++---
tsconfig.json | 1 +
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/src/middleware/jsx/index.test.tsx b/src/middleware/jsx/index.test.tsx
index 4bcd99d5..eb5c3a41 100644
--- a/src/middleware/jsx/index.test.tsx
+++ b/src/middleware/jsx/index.test.tsx
@@ -1,5 +1,5 @@
import { Hono } from '../../hono'
-import { h, jsx, memo } from '.'
+import { h, jsx, memo, Fragment } from '.'
describe('JSX middleware', () => {
const app = new Hono()
@@ -146,8 +146,8 @@ describe('memo', () => {
it('custom propsAreEqual', () => {
const Body = memo(
- ({ counter }: { counter: number, refresh?: boolean }) => {counter},
- (_, nextProps) => typeof nextProps.refresh == 'undefined' ? true : !nextProps.refresh
+ ({ counter }: { counter: number; refresh?: boolean }) => {counter},
+ (_, nextProps) => (typeof nextProps.refresh == 'undefined' ? true : !nextProps.refresh)
)
let template =
@@ -160,3 +160,25 @@ describe('memo', () => {
expect(template.toString()).toBe('2')
})
})
+
+describe('Fragment', () => {
+ it('Should render children', () => {
+ const template = (
+ <>
+
1
+ 2
+ >
+ )
+ expect(template.toString()).toBe('1
2
')
+ })
+
+ it('Should render nothing for empty Fragment', () => {
+ const template = <>>
+ expect(template.toString()).toBe('')
+ })
+
+ it('Should render nothing for undefined', () => {
+ const template = <>{undefined}>
+ expect(template.toString()).toBe('')
+ })
+})
diff --git a/src/middleware/jsx/index.ts b/src/middleware/jsx/index.ts
index 8f52c270..08ccc7d1 100644
--- a/src/middleware/jsx/index.ts
+++ b/src/middleware/jsx/index.ts
@@ -32,7 +32,7 @@ export const h = (
return tag.call(null, { ...props, children: children.length <= 1 ? children[0] : children })
}
- let result = `<${tag}`
+ let result = tag !== '' ? `<${tag}` : ''
const propsKeys = Object.keys(props || {})
for (let i = 0, len = propsKeys.length; i < len; i++) {
@@ -53,7 +53,9 @@ export const h = (
result += ` ${propsKeys[i]}="${escape(v.toString())}"`
}
- result += '>'
+ if (tag !== '') {
+ result += '>'
+ }
const flattenChildren = children.flat(Infinity)
for (let i = 0, len = flattenChildren.length; i < len; i++) {
@@ -67,7 +69,9 @@ export const h = (
}
}
- result += `${tag}>`
+ if (tag !== '') {
+ result += `${tag}>`
+ }
const escapedString = new String(result) as EscapedString
escapedString.isEscaped = true
@@ -111,3 +115,7 @@ export const memo = (
return (computed ||= component(props))
}) as FC
}
+
+export const Fragment = (props: { key?: string; children?: any }): EscapedString => {
+ return h('', {}, ...(props.children || []))
+}
diff --git a/tsconfig.json b/tsconfig.json
index 58c6b1c5..2d1cffa0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,6 +20,7 @@
],
"jsx": "react",
"jsxFactory": "h",
+ "jsxFragmentFactory": "Fragment",
},
"include": [
"src/**/*.ts",