Add support for components defined in frontmatter (#637)
* fix: add support for components defined in frontmatter * chore: add changeset * test: update test to match example use case
This commit is contained in:
parent
b4f145a0e7
commit
42a6acee28
4 changed files with 43 additions and 1 deletions
14
.changeset/twelve-lions-tie.md
Normal file
14
.changeset/twelve-lions-tie.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add support for components defined in Frontmatter. Previously, the following code would throw an error. Now it is officially supported!
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
const { level = 1 } = Astro.props;
|
||||||
|
const Element = `h${level}`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<Element>Hello world!</Element>
|
||||||
|
```
|
|
@ -688,7 +688,21 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
|
||||||
componentInfo = components.get(componentNamespace);
|
componentInfo = components.get(componentNamespace);
|
||||||
}
|
}
|
||||||
if (!componentInfo && !isCustomElementTag(componentName)) {
|
if (!componentInfo && !isCustomElementTag(componentName)) {
|
||||||
throw new Error(`Unknown Component: ${componentName}`);
|
if (hydrationAttributes.method) {
|
||||||
|
throw new Error(`Unable to hydrate "${componentName}" because it is statically defined in the frontmatter script. Hydration directives may only be used on imported components.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Previously we would throw here, but this is valid!
|
||||||
|
// If the frontmatter script defines `const Element = 'h1'`,
|
||||||
|
// you should be able to statically render `<Element>`
|
||||||
|
|
||||||
|
if (curr === 'markdown') {
|
||||||
|
await pushMarkdownToBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
paren++;
|
||||||
|
buffers[curr] += `h(${componentName}, ${attributes ? generateAttributes(attributes) : 'null'}`;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (componentName === 'Markdown') {
|
if (componentName === 'Markdown') {
|
||||||
const { $scope } = attributes ?? {};
|
const { $scope } = attributes ?? {};
|
||||||
|
|
|
@ -95,4 +95,12 @@ Basics('Allows spread attributes with TypeScript (#521)', async ({ runtime }) =>
|
||||||
assert.equal($('#spread-ts').attr('c'), '2');
|
assert.equal($('#spread-ts').attr('c'), '2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Basics('Allows Components defined in frontmatter', async ({ runtime }) => {
|
||||||
|
const result = await runtime.load('/frontmatter-component');
|
||||||
|
const html = result.contents;
|
||||||
|
const $ = doc(html);
|
||||||
|
|
||||||
|
assert.equal($('h1').length, 1);
|
||||||
|
});
|
||||||
|
|
||||||
Basics.run();
|
Basics.run();
|
||||||
|
|
6
packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro
vendored
Normal file
6
packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
const { level = 1 } = Astro.props;
|
||||||
|
const Element = `h${level}`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<Element>Hello world!</Element>
|
Loading…
Reference in a new issue