feat(mdx): add MDX support and migrate markdown files to MDX

- Add @astrojs/mdx integration to enable MDX support
- Migrate all markdown files (.md) to MDX (.mdx) format
- Create HighlightBox component for enhanced content styling
- Update astro config to include MDX integration
- Add documentation guide for MDX integration
This commit is contained in:
joyzhao
2025-06-20 11:36:11 +08:00
parent a446ce68bd
commit 398093dde9
9 changed files with 857 additions and 54 deletions

View File

@@ -0,0 +1,136 @@
---
/**
* HighlightBox Component
*
* A versatile component for highlighting content in Markdown files with different styles and icons.
*
* Usage in Markdown:
* ```md
* <HighlightBox type="info" title="Information">
* This is some important information.
* </HighlightBox>
* ```
*/
import { Info, AlertTriangle, CheckCircle, HelpCircle, Lightbulb } from 'lucide-react';
interface Props {
/**
* The type of highlight box
* @default "info"
*/
type?: 'info' | 'warning' | 'success' | 'error' | 'tip' | 'note';
/**
* Optional title for the highlight box
*/
title?: string;
/**
* Optional custom icon (SVG string)
*/
icon?: string;
}
const {
type = 'info',
title,
icon
} = Astro.props;
// Define styles based on type
const styles = {
info: {
bg: 'bg-blue-500/10 dark:bg-blue-500/20',
border: 'border-blue-500/50 dark:border-blue-500/30',
title: 'text-blue-700 dark:text-blue-300',
icon: 'text-blue-500',
component: Info
},
warning: {
bg: 'bg-amber-500/10 dark:bg-amber-500/20',
border: 'border-amber-500/50 dark:border-amber-500/30',
title: 'text-amber-700 dark:text-amber-300',
icon: 'text-amber-500',
component: AlertTriangle
},
success: {
bg: 'bg-green-500/10 dark:bg-green-500/20',
border: 'border-green-500/50 dark:border-green-500/30',
title: 'text-green-700 dark:text-green-300',
icon: 'text-green-500',
component: CheckCircle
},
error: {
bg: 'bg-red-500/10 dark:bg-red-500/20',
border: 'border-red-500/50 dark:border-red-500/30',
title: 'text-red-700 dark:text-red-300',
icon: 'text-red-500',
component: AlertTriangle
},
tip: {
bg: 'bg-purple-500/10 dark:bg-purple-500/20',
border: 'border-purple-500/50 dark:border-purple-500/30',
title: 'text-purple-700 dark:text-purple-300',
icon: 'text-purple-500',
component: Lightbulb
},
note: {
bg: 'bg-gray-500/10 dark:bg-gray-500/20',
border: 'border-gray-500/50 dark:border-gray-500/30',
title: 'text-gray-700 dark:text-gray-300',
icon: 'text-gray-500',
component: HelpCircle
}
};
const style = styles[type];
const IconComponent = style.component;
// Default titles based on type if not provided
const defaultTitles = {
info: 'Information',
warning: 'Warning',
success: 'Success',
error: 'Error',
tip: 'Tip',
note: 'Note'
};
const displayTitle = title || defaultTitles[type];
---
<div class={`rounded-lg p-3 my-4 border ${style.bg} ${style.border}`}>
<div class="flex flex-col gap-2">
<div class="flex items-center gap-2">
<div class={`flex-shrink-0 flex items-center justify-center ${style.icon}`}>
{icon ? (
<Fragment set:html={icon} />
) : (
<IconComponent className="w-4 h-4" />
)}
</div>
{displayTitle && (
<h4 class={`text-sm font-medium flex items-center !m-0 ${style.title}`}>
{displayTitle}
</h4>
)}
</div>
<div class="prose dark:prose-invert max-w-none text-sm pl-1 highlight-content">
<slot />
</div>
<style>
/* 自定义内容样式 */
.highlight-content :global(p) {
margin: 0;
}
.highlight-content :global(ul) {
margin: 0;
}
.highlight-content :global(li) {
margin: 0.5em 0;
}
</style>
</div>
</div>