diff options
author | 2021-07-23 13:00:49 -0400 | |
---|---|---|
committer | 2021-07-23 13:00:49 -0400 | |
commit | 164489fbb2a5e84498b55e39f84c23cbbbda2f03 (patch) | |
tree | 97ff6a4db815578e202f45b6a3fc11b6e95eabd3 | |
parent | 0c729f248d8d6a5f789b689f6a1ed9d544ec3c3a (diff) | |
download | astro-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.md | 5 | ||||
-rw-r--r-- | packages/astro/src/internal/h.ts | 36 | ||||
-rw-r--r-- | packages/astro/test/astro-expr.test.js | 6 | ||||
-rw-r--r-- | packages/astro/test/fixtures/astro-expr/src/components/falsy.astro | 23 | ||||
-rw-r--r-- | packages/astro/test/fixtures/astro-expr/src/pages/falsy.astro | 7 |
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> |