summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@matthewphillips.info> 2021-07-23 13:00:49 -0400
committerGravatar GitHub <noreply@github.com> 2021-07-23 13:00:49 -0400
commit164489fbb2a5e84498b55e39f84c23cbbbda2f03 (patch)
tree97ff6a4db815578e202f45b6a3fc11b6e95eabd3
parent0c729f248d8d6a5f789b689f6a1ed9d544ec3c3a (diff)
downloadastro-164489fbb2a5e84498b55e39f84c23cbbbda2f03.tar.gz
astro-164489fbb2a5e84498b55e39f84c23cbbbda2f03.tar.zst
astro-164489fbb2a5e84498b55e39f84c23cbbbda2f03.zip
Correctly serialize falsey values at top-level of components (#834)
* Correctly serialize falsey values at top-level of components * Adding a changeset
-rw-r--r--.changeset/healthy-pants-rule.md5
-rw-r--r--packages/astro/src/internal/h.ts36
-rw-r--r--packages/astro/test/astro-expr.test.js6
-rw-r--r--packages/astro/test/fixtures/astro-expr/src/components/falsy.astro23
-rw-r--r--packages/astro/test/fixtures/astro-expr/src/pages/falsy.astro7
5 files changed, 61 insertions, 16 deletions
diff --git a/.changeset/healthy-pants-rule.md b/.changeset/healthy-pants-rule.md
new file mode 100644
index 000000000..d265f96f7
--- /dev/null
+++ b/.changeset/healthy-pants-rule.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix for `false` being rendered in conditionals
diff --git a/packages/astro/src/internal/h.ts b/packages/astro/src/internal/h.ts
index 470597999..411b743fd 100644
--- a/packages/astro/src/internal/h.ts
+++ b/packages/astro/src/internal/h.ts
@@ -5,6 +5,23 @@ export type HTag = string | AstroComponent;
const voidTags = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
+function* _children(children: Array<HChild>) {
+ for (let child of children) {
+ // Special: If a child is a function, call it automatically.
+ // This lets you do {() => ...} without the extra boilerplate
+ // of wrapping it in a function and calling it.
+ if (typeof child === 'function') {
+ yield child();
+ } else if (typeof child === 'string') {
+ yield child;
+ } else if (!child && child !== 0) {
+ // do nothing, safe to ignore falsey values.
+ } else {
+ yield child;
+ }
+ }
+}
+
/** Generator for primary h() function */
function* _h(tag: string, attrs: HProps, children: Array<HChild>) {
if (tag.toLowerCase() === '!doctype') {
@@ -32,20 +49,7 @@ function* _h(tag: string, attrs: HProps, children: Array<HChild>) {
return;
}
- for (let child of children) {
- // Special: If a child is a function, call it automatically.
- // This lets you do {() => ...} without the extra boilerplate
- // of wrapping it in a function and calling it.
- if (typeof child === 'function') {
- yield child();
- } else if (typeof child === 'string') {
- yield child;
- } else if (!child && child !== 0) {
- // do nothing, safe to ignore falsey values.
- } else {
- yield child;
- }
- }
+ yield * _children(children);
yield `</${tag}>`;
}
@@ -62,6 +66,6 @@ export async function h(tag: HTag, attrs: HProps, ...pChildren: Array<Promise<HC
}
/** Fragment helper, similar to React.Fragment */
-export function Fragment(_: HProps, ...children: Array<string>) {
- return children.join('');
+export function Fragment(_: HProps, ...children: Array<HChild>) {
+ return Array.from(_children(children)).join('');
}
diff --git a/packages/astro/test/astro-expr.test.js b/packages/astro/test/astro-expr.test.js
index 10d1909a4..87764b4e4 100644
--- a/packages/astro/test/astro-expr.test.js
+++ b/packages/astro/test/astro-expr.test.js
@@ -80,6 +80,12 @@ Expressions('Does not render falsy values using &&', async ({ runtime }) => {
assert.equal($('#false').length, 0, `Expected {false && <span id="false" />} not to render`);
assert.equal($('#null').length, 0, `Expected {null && <span id="null" />} not to render`);
assert.equal($('#undefined').length, 0, `Expected {undefined && <span id="undefined" />} not to render`);
+
+ // Inside of a component
+ assert.equal($('#frag-true').length, 1, `Expected {true && <span id="true" />} to render`);
+ assert.equal($('#frag-false').length, 0, `Expected {false && <span id="false" />} not to render`);
+ assert.equal($('#frag-null').length, 0, `Expected {null && <span id="null" />} not to render`);
+ assert.equal($('#frag-undefined').length, 0, `Expected {undefined && <span id="undefined" />} not to render`);
});
Expressions.run();
diff --git a/packages/astro/test/fixtures/astro-expr/src/components/falsy.astro b/packages/astro/test/fixtures/astro-expr/src/components/falsy.astro
new file mode 100644
index 000000000..544deaf7b
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-expr/src/components/falsy.astro
@@ -0,0 +1,23 @@
+---
+const { items, emptyItems } = Astro.props;
+
+const internal = [];
+---
+
+<!-- False -->
+{false && (
+ <span id="frag-false" />
+)}
+
+<!-- Null -->
+{null && (
+ <span id="frag-null" />
+)}
+
+<!-- True -->
+{true && (
+ <span id="frag-true" />
+)}
+
+<!-- Undefined -->
+{false && (<span id="frag-undefined" />)} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/astro-expr/src/pages/falsy.astro b/packages/astro/test/fixtures/astro-expr/src/pages/falsy.astro
index 294f71684..39c56e252 100644
--- a/packages/astro/test/fixtures/astro-expr/src/pages/falsy.astro
+++ b/packages/astro/test/fixtures/astro-expr/src/pages/falsy.astro
@@ -1,3 +1,6 @@
+---
+import Falsey from '../components/falsy.astro';
+---
<html lang="en">
<head>
<title>My site</title>
@@ -8,5 +11,9 @@
{undefined && <span id="undefined" />}
{true && <span id="true" />}
<span id="zero">{0 && "VALUE"}</span>
+
+ <section id="fragment-container">
+ <Falsey />
+ </section>
</body>
</html>