Skip to content

Commit

Permalink
Merge pull request #8 from zhuba-Ahhh/dev
Browse files Browse the repository at this point in the history
feat: ✨ 兼容mdx文件直接渲染 & font
  • Loading branch information
zhuba-Ahhh authored Aug 27, 2024
2 parents fd5956a + 06e53c0 commit 50eb6a8
Show file tree
Hide file tree
Showing 11 changed files with 330 additions and 34 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"framer-motion": "^11.3.29",
"lodash-es": "^4.17.21",
"lucide-react": "^0.429.0",
"lxgw-wenkai-lite-webfont": "^1.7.0",
"next": "^14.2.6",
"next-mdx-remote": "^5.0.0",
"next-themes": "^0.3.0",
Expand All @@ -34,11 +35,11 @@
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@next/bundle-analyzer": "^14.2.6",
"@mdx-js/loader": "^3.0.1",
"@next/bundle-analyzer": "^14.2.6",
"@next/mdx": "^14.2.6",
"@types/mdx": "^2.0.13",
"@types/lodash-es": "^4.17.12",
"@types/mdx": "^2.0.13",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
Expand Down
6 changes: 5 additions & 1 deletion src/app/blog/[id]/AnimatedBlogPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ export default function AnimatedBlogPost({
transition={{ duration: 0.5, delay: 0.3 }}
>
<BlogHeader post={post} readingTime={readingTime} />
<BlogContent content={post.content} components={mdxComponents} />
<BlogContent
content={post.content}
contentFile={post?.contentFile}
components={mdxComponents}
/>
<BlogFooter post={post} />
<RelatedPosts posts={relatedPosts} />
<ShareButtons
Expand Down
44 changes: 28 additions & 16 deletions src/app/blog/[id]/BlogContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,40 @@ import remarkGfm from "remark-gfm";
import rehypeInlineCode from "@/lib/rehypeInlineCode";
import rehypeSlug from "rehype-slug";
import rehypeAutolinkHeadings from "rehype-autolink-headings";
import BlogPostMDXContent from "@/data/BlogPostMDXContent";

interface BlogContentProps {
content: string;
components: MDXComponents;
contentFile?: string;
}

export default function BlogContent({ content, components }: BlogContentProps) {
export default function BlogContent({
content,
components,
contentFile,
}: BlogContentProps) {
return (
<MDXRemote
source={content}
components={components}
options={{
mdxOptions: {
remarkPlugins: [remarkGfm],
rehypePlugins: [
rehypeSlug,
[rehypeAutolinkHeadings, { behavior: "wrap" }],
rehypeInlineCode,
],
},
parseFrontmatter: true,
}}
/>
<>
{contentFile ? (
<BlogPostMDXContent contentFile={contentFile} components={components} />
) : (
<MDXRemote
source={content}
components={components}
options={{
mdxOptions: {
remarkPlugins: [remarkGfm],
rehypePlugins: [
rehypeSlug,
[rehypeAutolinkHeadings, { behavior: "wrap" }],
rehypeInlineCode,
],
},
parseFrontmatter: true,
}}
/>
)}
</>
);
}
32 changes: 31 additions & 1 deletion src/app/blog/[id]/MdxComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ const CopyButton = dynamic(() => import("@/components/blog/id/CopyButton"), {
ssr: false,
});

const Table: React.FC<React.TableHTMLAttributes<HTMLTableElement>> = (
props
) => <table className="min-w-full divide-y divide-gray-200" {...props} />;

const Th: React.FC<React.ThHTMLAttributes<HTMLTableHeaderCellElement>> = (
props
) => (
<th
className="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
{...props}
/>
);

const Td: React.FC<React.TdHTMLAttributes<HTMLTableDataCellElement>> = (
props
) => (
<td
className="px-6 py-4 whitespace-nowrap text-sm text-gray-500"
{...props}
/>
);

const Tr: React.FC<React.HTMLAttributes<HTMLTableRowElement>> = (props) => (
<tr className="bg-white" {...props} />
);

export const mdxComponents: MDXComponents = {
h1: (props: any) => (
<h1
Expand Down Expand Up @@ -45,7 +71,7 @@ export const mdxComponents: MDXComponents = {
const match = /language-(\w+)/.exec(className || "");
const language = match ? match[1] : "text";
const isInline = className === "inline-code";
if (isInline) {
if (isInline || !className) {
return (
<code
className="bg-gray-100 dark:bg-gray-800 rounded px-1 py-0.5 font-mono text-sm"
Expand Down Expand Up @@ -74,4 +100,8 @@ export const mdxComponents: MDXComponents = {
);
},
pre: (props: any) => <div {...props} />,
table: Table,
th: Th,
td: Td,
tr: Tr,
};
11 changes: 1 addition & 10 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "@/style/globals.css";
import Header from "@/components/app/Header";
import Footer from "@/components/app/Footer";
Expand All @@ -11,8 +10,6 @@ import { ViewTransitions } from "next-view-transitions";
import { ThemeProvider } from "next-themes";
import AnimatedLayout from "@/components/app/AnimatedLayout";

const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });

export const metadata: Metadata = {
title: "我的博客",
description: "欢迎来到我的博客",
Expand All @@ -29,13 +26,7 @@ export default function RootLayout({
<head>
<link rel="icon" href="/next.svg" type="image/svg+xml" />
</head>
<body
className={cn(
`${inter.className} flex flex-col bg-background font-sans antialiased h-full`,
inter.variable,
"font-['LXGW_WenKai',sans-serif]"
)}
>
<body className={cn(`flex flex-col bg-background antialiased h-full`)}>
<ThemeProvider attribute="class">
<Header />
<AnimatedLayout>{children}</AnimatedLayout>
Expand Down
25 changes: 25 additions & 0 deletions src/data/BlogPostMDXContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import { MDXProvider } from "@mdx-js/react";
import dynamic from "next/dynamic";
import { MDXComponents } from "@/app/blog/[id]/types";

interface BlogPostMDXContent {
contentFile: string;
components: MDXComponents;
}

const BlogPostMDXContent = ({
contentFile,
components,
}: BlogPostMDXContent) => {
const MDXContent = dynamic(() => import(`./content/${contentFile}`));

return (
<MDXProvider components={components}>
{/* @ts-ignore */}
<MDXContent components={components} />
</MDXProvider>
);
};

export default BlogPostMDXContent;
2 changes: 2 additions & 0 deletions src/data/blogPosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ export interface BlogPost {
tags: string[];
category?: string;
coverImage?: string;
contentFile?: string; // 新增字段,指向mdx文件
}

export const blogPosts: BlogPost[] = [
{
id: 1,
title: "深入理解React Hooks",
excerpt: "探索React Hooks的工作原理和最佳实践...",
contentFile: "1.mdx",
content: `
# 深入理解React Hooks
Expand Down
Loading

0 comments on commit 50eb6a8

Please sign in to comment.