Skip to content

Commit

Permalink
fix(markdoc): use astro components defined with extends
Browse files Browse the repository at this point in the history
  • Loading branch information
HiDeoo committed Aug 27, 2024
1 parent b81b703 commit 0bab683
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/good-adults-punch.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 2 additions & 2 deletions packages/integrations/markdoc/src/content-entry-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import markdoc from '@astrojs/markdoc';
import { defineConfig } from 'astro/config';

// https://astro.build/config
export default defineConfig({
integrations: [markdoc()],
});
Original file line number Diff line number Diff line change
@@ -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'],
},
},
},
},
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "@test/markdoc-render-with-extends-components",
"version": "0.0.0",
"private": true,
"dependencies": {
"@astrojs/markdoc": "workspace:*",
"astro": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -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} />
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<marquee data-custom-marquee {...Astro.props}><slot /></marquee>
Original file line number Diff line number Diff line change
@@ -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;
```
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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');
}
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0bab683

Please sign in to comment.