mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
fix(markdoc): use astro components defined with extends
(#11846)
This commit is contained in:
parent
543e8f5b78
commit
ed7bbd990f
11 changed files with 176 additions and 2 deletions
5
.changeset/good-adults-punch.md
Normal file
5
.changeset/good-adults-punch.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/markdoc': patch
|
||||
---
|
||||
|
||||
Fixes an issue preventing to use Astro components as Markdoc tags and nodes when configured using the `extends` property.
|
|
@ -78,13 +78,13 @@ export async function getContentEntryType({
|
|||
// Only include component imports for tags used in the document.
|
||||
// Avoids style and script bleed.
|
||||
for (const tag of usedTags) {
|
||||
const render = userMarkdocConfig.tags?.[tag]?.render;
|
||||
const render = markdocConfig.tags?.[tag]?.render;
|
||||
if (isComponentConfig(render)) {
|
||||
componentConfigByTagMap[tag] = render;
|
||||
}
|
||||
}
|
||||
let componentConfigByNodeMap: Record<string, ComponentConfig> = {};
|
||||
for (const [nodeType, schema] of Object.entries(userMarkdocConfig.nodes ?? {})) {
|
||||
for (const [nodeType, schema] of Object.entries(markdocConfig.nodes ?? {})) {
|
||||
const render = schema?.render;
|
||||
if (isComponentConfig(render)) {
|
||||
componentConfigByNodeMap[nodeType] = render;
|
||||
|
|
7
packages/integrations/markdoc/test/fixtures/render-with-extends-components/astro.config.mjs
vendored
Normal file
7
packages/integrations/markdoc/test/fixtures/render-with-extends-components/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import markdoc from '@astrojs/markdoc';
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [markdoc()],
|
||||
});
|
31
packages/integrations/markdoc/test/fixtures/render-with-extends-components/markdoc.config.ts
vendored
Normal file
31
packages/integrations/markdoc/test/fixtures/render-with-extends-components/markdoc.config.ts
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { component, defineMarkdocConfig } from '@astrojs/markdoc/config';
|
||||
|
||||
export default defineMarkdocConfig({
|
||||
extends: [preset()],
|
||||
});
|
||||
|
||||
function preset() {
|
||||
return {
|
||||
nodes: {
|
||||
fence: {
|
||||
render: component('./src/components/Code.astro'),
|
||||
attributes: {
|
||||
language: { type: String },
|
||||
content: { type: String },
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: {
|
||||
'marquee-element': {
|
||||
render: component('./src/components/CustomMarquee.astro'),
|
||||
attributes: {
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'left',
|
||||
matches: ['left', 'right', 'up', 'down'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
9
packages/integrations/markdoc/test/fixtures/render-with-extends-components/package.json
vendored
Normal file
9
packages/integrations/markdoc/test/fixtures/render-with-extends-components/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/markdoc-render-with-extends-components",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/markdoc": "workspace:*",
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
import { Code } from 'astro/components';
|
||||
|
||||
type Props = {
|
||||
content: string;
|
||||
language: string;
|
||||
}
|
||||
|
||||
const { content, language } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<Code lang={language} code={content} />
|
|
@ -0,0 +1 @@
|
|||
<marquee data-custom-marquee {...Astro.props}><slot /></marquee>
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: Post with components
|
||||
---
|
||||
|
||||
## Post with components
|
||||
|
||||
This uses a custom marquee component with a shortcode:
|
||||
|
||||
{% marquee-element direction="right" %}
|
||||
I'm a marquee too!
|
||||
{% /marquee-element %}
|
||||
|
||||
And a code component for code blocks:
|
||||
|
||||
```js
|
||||
const isRenderedWithShiki = true;
|
||||
```
|
19
packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/pages/index.astro
vendored
Normal file
19
packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
import { getEntryBySlug } from "astro:content";
|
||||
|
||||
const post = await getEntryBySlug('blog', 'with-components');
|
||||
const { Content } = await post.render();
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Content</title>
|
||||
</head>
|
||||
<body>
|
||||
<Content />
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,64 @@
|
|||
import assert from 'node:assert/strict';
|
||||
import { after, before, describe, it } from 'node:test';
|
||||
import { parseHTML } from 'linkedom';
|
||||
import { loadFixture } from '../../../astro/test/test-utils.js';
|
||||
|
||||
const root = new URL('./fixtures/render-with-extends-components/', import.meta.url);
|
||||
|
||||
describe('Markdoc - render components defined in `extends`', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root,
|
||||
});
|
||||
});
|
||||
|
||||
describe('dev', () => {
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
it('renders content - with components', async () => {
|
||||
const res = await fixture.fetch('/');
|
||||
const html = await res.text();
|
||||
|
||||
renderComponentsChecks(html);
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('renders content - with components', async () => {
|
||||
const html = await fixture.readFile('/index.html');
|
||||
|
||||
renderComponentsChecks(html);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/** @param {string} html */
|
||||
function renderComponentsChecks(html) {
|
||||
const { document } = parseHTML(html);
|
||||
const h2 = document.querySelector('h2');
|
||||
assert.equal(h2.textContent, 'Post with components');
|
||||
|
||||
// Renders custom shortcode component
|
||||
const marquee = document.querySelector('marquee');
|
||||
assert.notEqual(marquee, null);
|
||||
assert.equal(marquee.hasAttribute('data-custom-marquee'), true);
|
||||
|
||||
// Renders Astro Code component
|
||||
const pre = document.querySelector('pre');
|
||||
assert.notEqual(pre, null);
|
||||
assert.equal(pre.className, 'astro-code github-dark');
|
||||
}
|
|
@ -4744,6 +4744,15 @@ importers:
|
|||
specifier: workspace:*
|
||||
version: link:../../../../../astro
|
||||
|
||||
packages/integrations/markdoc/test/fixtures/render-with-extends-components:
|
||||
dependencies:
|
||||
'@astrojs/markdoc':
|
||||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../../../../astro
|
||||
|
||||
packages/integrations/markdoc/test/fixtures/render-with-indented-components:
|
||||
dependencies:
|
||||
'@astrojs/markdoc':
|
||||
|
|
Loading…
Reference in a new issue