Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat Custom components #8

Merged
merged 17 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4a9de8b
feat: Add custom component to markdown-remark integration
Adammatthiesen Jan 6, 2025
906c188
Refactor markdown-remark integration to remove unused code
Adammatthiesen Jan 6, 2025
81ba48c
Refactor markdown-remark integration to remove unused code
Adammatthiesen Jan 6, 2025
9b9bf99
Refactor markdown-remark integration to clean up code
Adammatthiesen Jan 6, 2025
a1da582
Refactor markdown-remark integration to remove unused code and optimi…
Adammatthiesen Jan 6, 2025
2f76ef6
Refactor markdown-remark integration to optimize component exports
Adammatthiesen Jan 6, 2025
bd0ee28
Refactor markdown-remark integration to optimize component exports an…
Adammatthiesen Jan 6, 2025
5cb8b0f
Refactor markdown-remark integration to optimize component exports an…
Adammatthiesen Jan 6, 2025
6fb40fd
Refactor markdown-remark integration to optimize component exports an…
Adammatthiesen Jan 6, 2025
b2ef01d
add changeset
Adammatthiesen Jan 6, 2025
f37a095
Refactor markdown-remark integration to include callouts in shared state
Adammatthiesen Jan 6, 2025
9a32164
ensure all components are auto-converted to lowercase so they meet HT…
Adammatthiesen Jan 6, 2025
19dddd1
refactor config
Adammatthiesen Jan 6, 2025
bcc7337
Refactor markdown-remark integration to optimize config
Adammatthiesen Jan 6, 2025
2b0ae42
Refactor markdown-remark integration to update import paths
Adammatthiesen Jan 6, 2025
7125e52
Update readme to match new schema
Adammatthiesen Jan 6, 2025
ccfbf94
Refactor markdown-remark integration to update import paths and optim…
Adammatthiesen Jan 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .changeset/wicked-bikes-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"@studiocms/markdown-remark": minor
---

Introduce custom User-Defined component handling.

This update includes significant enhancements to the Markdown Remark processor Astro Integration, allowing for more flexible and powerful Markdown rendering with custom components.

### New Features:

- Added custom components support in the Markdown Remark processor Astro Integration.
- Introduced utility functions in `utils.ts` for component proxy creation, indentation handling, dedenting strings, and merging records.
- Moved zod schema to separate `schema.ts` file.

### Integration Updates:

- Enhanced Astro integration to support custom components configuration via `astro.config.mjs`.
- Updated `markdown.ts` to include custom components during Markdown rendering.
- Extended `index.ts` to utilize the new schema and utilities.

### Documentation:

- Updated `README.md` with instructions for setting up custom components in Astro integration.

### Dependencies:

- Added `entities` and `ultrahtml` as new dependencies.
28 changes: 25 additions & 3 deletions packages/markdown-remark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pnpm add @studiocms/markdown-remark

### As an Astro Integration

With the Astro integration enabled, you can either pass in custom components into your astro config, or manually for the specific render your trying to do shown in the following methods.

#### Setup the integration

**`astro.config.mjs`**
Expand All @@ -44,7 +46,24 @@ export default defineConfig({
* https://docs.astro.build/en/reference/configuration-reference/#markdown-options
*/
},
integrations: [markdownRemark()],
integrations: [markdownRemark({
// Used for injecting CSS for Headings and Callouts
injectCSS: true,
// User defined components that will be used when processing markdown
components: {
// Example of a custom defined component
custom: "./src/components/Custom.astro",
},
// Custom Markdown config
markdown: {
// Configure the available callout themes
callouts: {
theme: 'obsidian' // Can also be 'github' or 'vitepress'
},
autoLinkHeadings: true,
sanitize: {} // see https://github.com/natemoo-re/ultrahtml?tab=readme-ov-file#sanitization for full options
}
})],
});
```

Expand All @@ -55,6 +74,7 @@ export default defineConfig({
```astro
---
import { Markdown } from 'studiocms:markdown-remark';
import Custom from '../components/Custom.astro';
---
<html>
<head>
Expand All @@ -63,7 +83,7 @@ import { Markdown } from 'studiocms:markdown-remark';
<title>Example</title>
</head>
<body>
<Markdown content={`# Hello World!`} />
<Markdown content={`# Hello World! <custom></custom>`} components={{ custom: Custom }} />
</body>
</html>
```
Expand All @@ -73,8 +93,10 @@ OR
```astro
---
import { render } from 'studiocms:markdown-remark';
import Custom from '../components/Custom.astro';

const { html } = render('# Hello World!')
// @ts-ignore
const { html } = render('# Hello World! <custom></custom>', {}, { $$result, {custom: Custom} })
---
<html>
<head>
Expand Down
2 changes: 2 additions & 0 deletions packages/markdown-remark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"dependencies": {
"@astrojs/prism": "^3.2.0",
"astro-integration-kit": "^0.18.0",
"entities": "^6.0.0",
"github-slugger": "^2.0.0",
"hastscript": "^9.0.0",
"hast-util-from-html": "^2.0.3",
Expand All @@ -64,6 +65,7 @@
"remark-rehype": "^11.1.1",
"remark-smartypants": "^3.0.2",
"shiki": "^1.23.1",
"ultrahtml": "^1.5.3",
"unified": "^11.0.5",
"unist-util-remove-position": "^5.0.0",
"unist-util-visit": "^5.0.0",
Expand Down
6 changes: 5 additions & 1 deletion packages/markdown-remark/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export * from './processor/index.js';
export { markdownRemark, markdownRemark as default } from './integration/index.js';
export {
markdownRemark,
default,
type StudioCMSMarkdownRemarkOptions,
} from './integration/index.js';
94 changes: 53 additions & 41 deletions packages/markdown-remark/src/integration/index.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,78 @@
import type { AstroIntegration } from 'astro';
import { addVirtualImports, createResolver } from 'astro-integration-kit';
import { z } from 'astro/zod';
import {
type StudioCMSMarkdownRemarkOptions,
StudioCMSMarkdownRemarkOptionsSchema,
} from './schema.js';
import { shared } from './shared.js';

const MarkdownRemarkOptionsSchema = z
.object({
/**
* Inject CSS for Rehype autolink headings styles.
*/
injectCSS: z.boolean().optional().default(true),

/**
* Options for the Markdown processor.
*/
markdown: z
.object({
/**
* Configures the callouts theme.
*/
callouts: z
.object({
/**
* The theme to use for callouts.
*/
theme: z
.union([z.literal('github'), z.literal('obsidian'), z.literal('vitepress')])
.optional()
.default('obsidian'),
})
.optional()
.default({}),
})
.optional()
.default({}),
})
.optional()
.default({});

export type MarkdownRemarkOptions = typeof MarkdownRemarkOptionsSchema._input;
export type { StudioCMSMarkdownRemarkOptions } from './schema.js';

/**
* Integrates the Markdown Remark processor into Astro available as `studiocms:markdown-remark`.
*
* @param {MarkdownRemarkOptions} opts Options for the Markdown Remark processor.
* @param {StudioCMSMarkdownRemarkOptions} opts Options for the Markdown Remark processor.
* @returns Astro integration.
*/
export function markdownRemark(opts?: MarkdownRemarkOptions): AstroIntegration {
const { injectCSS, markdown } = MarkdownRemarkOptionsSchema.parse(opts);
export function markdownRemark(opts?: StudioCMSMarkdownRemarkOptions): AstroIntegration {
// Parse the options
const { injectCSS, components, markdownExtended } =
StudioCMSMarkdownRemarkOptionsSchema.parse(opts);

// Create a resolver for the current file
const { resolve } = createResolver(import.meta.url);

// Resolve the callout theme based on the user's configuration
const resolvedCalloutTheme = resolve(
`../../assets/callout-themes/${markdown.callouts.theme}.css`
`../../assets/callout-themes/${markdownExtended.callouts.theme}.css`
);

return {
name: '@studiocms/markdown-remark',
hooks: {
'astro:config:setup'(params) {
// Create a resolver for the Astro project root
const { resolve: astroRootResolve } = createResolver(params.config.root.pathname);

// Add virtual imports for the Markdown Remark processor
addVirtualImports(params, {
name: '@studiocms/markdown-remark',
imports: {
// The main Markdown Remark processor
'studiocms:markdown-remark': `export * from '${resolve('./markdown.js')}';`,
// Styles for the Markdown Remark processor
'studiocms:markdown-remark/css': `
import '${resolve('../../assets/headings.css')}';
import '${resolvedCalloutTheme}';
${markdownExtended.callouts.enabled ? `import '${resolvedCalloutTheme}';` : ''}
`,
// User defined components for the Markdown processor
'studiocms:markdown-remark/user-components': `
export const componentKeys = ${JSON.stringify(Object.keys(components).map((name) => name.toLowerCase()))};

${Object.entries(components)
.map(
([name, path]) =>
`export { default as ${name.toLowerCase()} } from '${astroRootResolve(path)}';`
)
.join('\n')}
`,
},
});

// Inject the CSS for the Markdown processor if enabled
if (injectCSS) {
params.injectScript('page-ssr', 'import "studiocms:markdown-remark/css";');
}
},
'astro:config:done'({ injectTypes, config }) {
// Create a resolver for the Astro project root
const { resolve: astroRootResolve } = createResolver(config.root.pathname);

// Inject the Markdown configuration into the shared state
shared.markdownConfig = config.markdown;
shared.studiocms = markdownExtended;

// Inject types for the Markdown Remark processor
injectTypes({
filename: 'render.d.ts',
content: `// This file is generated by @studiocms/markdown-remark
Expand All @@ -84,9 +83,22 @@ export function markdownRemark(opts?: MarkdownRemarkOptions): AstroIntegration {
export type Props = import('${resolve('./markdown.js')}').Props;
export type RenderResponse = import('${resolve('./markdown.js')}').RenderResponse;
}

declare module 'studiocms:markdown-remark/user-components' {
export const componentKeys: string[];

${Object.entries(components)
.map(
([name, path]) =>
`export const ${name.toLowerCase()}: typeof import('${astroRootResolve(path)}').default;`
)
.join('\n')}
}
`,
});
},
},
};
}

export default markdownRemark;
Loading
Loading