Serialize boolean attributes without a value (#422)
* Serialize boolean attributes without a value Fixes #307 * Update the attrs test * Adds a changeset * Adds test that components receive booleans
This commit is contained in:
parent
42dee7978d
commit
2d854092a4
7 changed files with 41 additions and 4 deletions
5
.changeset/sour-squids-trade.md
Normal file
5
.changeset/sour-squids-trade.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes serialization of boolean attributes
|
|
@ -1,4 +1,4 @@
|
|||
export type HProps = Record<string, string> | null | undefined;
|
||||
export type HProps = Record<string, string | boolean> | null | undefined;
|
||||
export type HChild = string | undefined | (() => string);
|
||||
export type AstroComponent = (props: HProps, ...children: Array<HChild>) => string;
|
||||
export type HTag = string | AstroComponent;
|
||||
|
@ -20,7 +20,8 @@ function* _h(tag: string, attrs: HProps, children: Array<HChild>) {
|
|||
if (attrs) {
|
||||
for (let [key, value] of Object.entries(attrs)) {
|
||||
if (value === '') yield ` ${key}=""`;
|
||||
else if (value == null) yield '';
|
||||
else if (value == null || value === false) yield '';
|
||||
else if (value === true) yield ` ${key}`;
|
||||
else yield ` ${key}="${value}"`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ Attributes('Passes attributes to elements as expected', async ({ runtime }) => {
|
|||
const $ = doc(result.contents);
|
||||
|
||||
const ids = ['false-str', 'true-str', 'false', 'true', 'empty', 'null', 'undefined'];
|
||||
const specs = ['false', 'true', 'false', 'true', '', undefined, undefined];
|
||||
const specs = ['false', 'true', undefined, '', '', undefined, undefined];
|
||||
|
||||
let i = 0;
|
||||
for (const id of ids) {
|
||||
|
@ -25,4 +25,15 @@ Attributes('Passes attributes to elements as expected', async ({ runtime }) => {
|
|||
}
|
||||
});
|
||||
|
||||
Attributes('Passes boolean attributes to components as expected', async ({ runtime }) => {
|
||||
const result = await runtime.load('/component');
|
||||
if (result.error) throw new Error(result.error);
|
||||
|
||||
const $ = doc(result.contents);
|
||||
assert.equal($('#true').attr('attr'), 'attr-true');
|
||||
assert.equal($('#true').attr('type'), 'boolean');
|
||||
assert.equal($('#false').attr('attr'), 'attr-false');
|
||||
assert.equal($('#false').attr('type'), 'boolean');
|
||||
});
|
||||
|
||||
Attributes.run();
|
||||
|
|
|
@ -32,4 +32,12 @@ Basics('Does not set the HMR port when no dynamic component used', async ({ runt
|
|||
assert.ok(!/HMR_WEBSOCKET_URL/.test(html), 'Does not set the websocket port');
|
||||
});
|
||||
|
||||
Basics('Correctly serializes boolean attributes', async ({ runtime }) => {
|
||||
const result = await runtime.load('/');
|
||||
const html = result.contents;
|
||||
const $ = doc(html);
|
||||
assert.equal($('h1').attr('data-something'), '');
|
||||
assert.equal($('h2').attr('not-data-ok'), '');
|
||||
});
|
||||
|
||||
Basics.run();
|
||||
|
|
5
packages/astro/test/fixtures/astro-attrs/src/components/Span.jsx
vendored
Normal file
5
packages/astro/test/fixtures/astro-attrs/src/components/Span.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function({ id, attr }) {
|
||||
return <span id={id} attr={`attr-${attr}`} type={typeof attr}></span>
|
||||
}
|
6
packages/astro/test/fixtures/astro-attrs/src/pages/component.astro
vendored
Normal file
6
packages/astro/test/fixtures/astro-attrs/src/pages/component.astro
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
import Span from '../components/Span.jsx';
|
||||
---
|
||||
|
||||
<Span id="true" attr={true} />
|
||||
<Span id="false" attr={false} />
|
|
@ -7,6 +7,7 @@ let title = 'My App'
|
|||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
<h1 data-something>Hello world!</h1>
|
||||
<h2 not-data-ok>Subtitle here</h2>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue