diff --git a/packages/jsx/src/index.test.tsx b/packages/jsx/src/index.test.tsx
index 3409b5e8e..d76d317ff 100644
--- a/packages/jsx/src/index.test.tsx
+++ b/packages/jsx/src/index.test.tsx
@@ -262,4 +262,86 @@ test('linked list', () => {
// assert.not.ok(isConnected(ctx, jsxList))
})
+test('boolean as child', () => {
+ const { h, hf } = setup()
+
+ const trueAtom = atom(true, 'true')
+ const trueValue = true
+ const falseAtom = atom(false, 'false')
+ const falseValue = false
+
+ const element =
+ {trueAtom}
+ {trueValue}
+ {falseAtom}
+ {falseValue}
+
+
+ assert.is(element.childNodes.length, 2)
+ assert.is(element.textContent, '')
+})
+
+test('null as child', () => {
+ const { h, hf } = setup()
+
+ const nullAtom = atom(null, 'null')
+ const nullValue = null
+
+ const element =
+ {nullAtom}
+ {nullValue}
+
+
+ assert.is(element.childNodes.length, 1)
+ assert.is(element.textContent, '')
+})
+
+test('undefined as child', () => {
+ const { h, hf } = setup()
+
+ const undefinedAtom = atom(undefined, 'undefined')
+ const undefinedValue = undefined
+
+ const element =
+ {undefinedAtom}
+ {undefinedValue}
+
+
+ assert.is(element.childNodes.length, 1)
+ assert.is(element.textContent, '')
+})
+
+test('empty string as child', () => {
+ const { h, hf } = setup()
+
+ const emptyStringAtom = atom('', 'emptyString')
+ const emptyStringValue = ''
+
+ const element =
+ {emptyStringAtom}
+ {emptyStringValue}
+
+
+ assert.is(element.childNodes.length, 1)
+ assert.is(element.textContent, '')
+})
+
+test('update skipped atom', () => {
+ const { ctx, h, hf, mount, parent } = setup()
+
+ const valueAtom = atom(undefined, 'value')
+
+ const element = {valueAtom}
+
+ mount(parent, element)
+
+ assert.is(parent.childNodes.length, 1)
+ assert.is(parent.textContent, '')
+
+ valueAtom(ctx, 123)
+
+ assert.is(parent.childNodes.length, 1)
+ assert.is(parent.textContent, '123')
+})
+
test.run()
diff --git a/packages/jsx/src/index.ts b/packages/jsx/src/index.ts
index 7f21a777b..36154e80a 100644
--- a/packages/jsx/src/index.ts
+++ b/packages/jsx/src/index.ts
@@ -32,6 +32,8 @@ type DomApis = Pick<
| 'DocumentFragment'
>
+const isSkipped = (value: unknown): value is boolean | '' | null | undefined => typeof value === 'boolean' || value === '' || value == null
+
let unsubscribesMap = new WeakMap>()
let unlink = (parent: any, un: Unsubscribe) => {
// check the connection in the next tick
@@ -241,7 +243,7 @@ export const reatomJsx = (ctx: Ctx, DOM: DomApis = globalThis.window) => {
}
} else {
// TODO more tests
- innerChild.textContent = String(v)
+ innerChild.textContent = isSkipped(v) ? '' : String(v)
}
}
} catch (e) {
@@ -251,7 +253,7 @@ export const reatomJsx = (ctx: Ctx, DOM: DomApis = globalThis.window) => {
if (error) throw error
unlink(element, un)
element.appendChild(innerChild)
- } else {
+ } else if (!isSkipped(child)) {
element.appendChild(
isObject(child) && 'nodeType' in child
? (child as JSX.Element)
diff --git a/packages/jsx/src/jsx.d.ts b/packages/jsx/src/jsx.d.ts
index 5cf8dcd28..fc484582a 100644
--- a/packages/jsx/src/jsx.d.ts
+++ b/packages/jsx/src/jsx.d.ts
@@ -1,4 +1,4 @@
-/*
+/*
Respectfully copied from https://github.com/ryansolid/dom-expressions/blob/ae71a417aa13b33517082628aff09513629df8b2/packages/dom-expressions/src/jsx.d.ts
*/