remark-code-to-slot
v0.5.1
Published
A remark plugin to convert code blocks to slots
Maintainers
Readme
remark-code-to-slot
A remark plugin to convert code blocks to slots with data attributes.
Installation
npm install -D remark-code-to-slotUsage
import createMDX from '@next/mdx';
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
};
const withMDX = createMDX({
options: {
remarkPlugins: ['remark-code-to-slot'],
rehypePlugins: [],
},
});
export default withMDX(nextConfig);React Integration
Using the helper function (Recommended)
mdx-components.tsx
import type { MDXComponents } from "mdx/types";
import { CodeSlot } from "@/components/CodeSlot";
import { createCodeSlotRenderer } from "remark-code-to-slot";
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
div: createCodeSlotRenderer({
render: ({ groups, codes }) => (
<CodeSlot groups={groups} codes={codes} />
),
fallback: (props) => <div {...props} /> // Optional
}),
};
}The createCodeSlotRenderer helper:
- Provides full TypeScript type safety
- Automatically handles data attribute parsing
- Single unified
renderfunction for both code groups and single blocks - Optional
fallbackfunction for regular divs
Example Component Implementation
CodeSlot.tsx
import type { RemarkCodeGroup } from "remark-code-to-slot";
export function CodeSlot({
groups,
codes
}: {
groups: string[];
codes: RemarkCodeGroup['codes'];
}) {
// groups: array of unique group identifiers (e.g., ["npm", "bun", "pnpm"])
// codes: array of { lang, code, title, group? }
// Single code block
if (codes.length === 1) {
const code = codes[0];
return <pre><code>{code.code}</code></pre>;
}
// Multiple code blocks (code group)
return <div>{/* render tabs or similar UI */}</div>;
}Manual usage (Advanced)
If you need more control, you can use the parser functions directly:
import type { MDXComponents } from "mdx/types";
import { CodeSlot } from "@/components/CodeSlot";
import { parseRemarkCode } from "remark-code-to-slot";
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
div: (props: any) => {
if (props["remark-code-data"]) {
const data = parseRemarkCode(props["remark-code-data"]);
return <CodeSlot groups={data.groups} codes={data.codes} />;
}
return <div {...props} />;
},
};
}Type Definitions
The helper function provides proper TypeScript types:
import type { ReactElement } from "react";
import type { RemarkCodeGroup } from "remark-code-to-slot";
interface CreateCodeSlotRendererOptions {
render: (data: RemarkCodeGroup) => ReactElement;
fallback?: (props: DivProps) => ReactElement;
}
function createCodeSlotRenderer(
options: CreateCodeSlotRendererOptions
): ComponentType<DivProps>;
// Data structure
interface RemarkCodeGroup {
groups: string[];
codes: CodeItem[];
}
interface CodeItem {
lang: string;
code: string;
title: string;
group?: string;
}