Files
david_bai 27375c1a4d refactor(theme): use design tokens and fix dark mode visuals
- Replace hardcoded Tailwind colors (bg-white, bg-gray-50/100, text-gray-, border-gray-, divide-gray-*, text-blue-600/800, bg-blue-50) with design tokens (bg-card, bg-muted, text-foreground, text-muted-foreground, border-
    border, text-primary, hover:bg-accent, bg-primary/10).
  - ClipboardApp: update RichTextEditor toolbar/editor, FileUploadHandler, ShareCard, FileListDisplay, SendTabPanel, RetrieveTabPanel, FileTransferButton.
  - Blog UI: unify styles in list page, tag page, post page, ArticleListItem, and TableOfContents.
  - MDX/prose: normalize pre/code/table/blockquote/lists and figure captions; switch rehype table divider to theme token.
  - Misc: adjust HomeClient and HowItWorks copy colors to tokens.
  - No functional changes; light mode parity; improved contrast and consistency in dark mode.
2025-11-25 21:52:45 +08:00

197 lines
5.1 KiB
TypeScript

import Image from "next/image";
import { ComponentProps, DetailedHTMLProps, HTMLAttributes } from "react";
import dynamic from "next/dynamic";
// Dynamically import the Mermaid component
const Mermaid = dynamic(() => import("@/components/blog/Mermaid"), {
ssr: false,
});
export type MDXComponents = {
p: (
props: DetailedHTMLProps<
HTMLAttributes<HTMLParagraphElement>,
HTMLParagraphElement
>
) => JSX.Element;
img: (props: ComponentProps<"img">) => JSX.Element;
pre: (
props: DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>
) => JSX.Element;
code: (
props: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>
) => JSX.Element;
table: (
props: DetailedHTMLProps<HTMLAttributes<HTMLTableElement>, HTMLTableElement>
) => JSX.Element;
thead: (
props: DetailedHTMLProps<
HTMLAttributes<HTMLTableSectionElement>,
HTMLTableSectionElement
>
) => JSX.Element;
tbody: (
props: DetailedHTMLProps<
HTMLAttributes<HTMLTableSectionElement>,
HTMLTableSectionElement
>
) => JSX.Element;
tr: (
props: DetailedHTMLProps<
HTMLAttributes<HTMLTableRowElement>,
HTMLTableRowElement
>
) => JSX.Element;
th: (
props: DetailedHTMLProps<
HTMLAttributes<HTMLTableCellElement>,
HTMLTableCellElement
>
) => JSX.Element;
td: (
props: DetailedHTMLProps<
HTMLAttributes<HTMLTableCellElement>,
HTMLTableCellElement
>
) => JSX.Element;
blockquote: (
props: DetailedHTMLProps<HTMLAttributes<HTMLQuoteElement>, HTMLQuoteElement>
) => JSX.Element;
ul: (
props: DetailedHTMLProps<HTMLAttributes<HTMLUListElement>, HTMLUListElement>
) => JSX.Element;
ol: (
props: DetailedHTMLProps<HTMLAttributes<HTMLOListElement>, HTMLOListElement>
) => JSX.Element;
li: (
props: DetailedHTMLProps<HTMLAttributes<HTMLLIElement>, HTMLLIElement>
) => JSX.Element;
mermaid: React.ComponentType<{ children: string }>;
};
// Custom MDX components
export const mdxComponents: MDXComponents = {
p: ({ children, ...props }) => (
<div className="mb-6 leading-relaxed text-foreground" {...props}>
{children}
</div>
),
img: (props) => {
const { src, ...rest } = props;
if (!src) {
return <div className="my-8">Image source is missing</div>;
}
return (
<div className="my-8">
<Image
src={src}
{...rest}
width={800}
height={400}
className="rounded-lg w-full"
alt={props.alt || ""}
/>
{props.alt && (
<div className="text-center text-sm text-muted-foreground mt-2 italic">
{props.alt}
</div>
)}
</div>
);
},
pre: ({ children, ...props }) => (
<pre
className="relative my-6 rounded-lg bg-muted border border-border p-4 overflow-x-auto"
{...props}
>
{children}
</pre>
),
code: ({ children, className, ...props }) => {
const isInlineCode = !className;
return isInlineCode ? (
<code
className="bg-muted rounded px-1.5 py-0.5 text-foreground border border-border text-sm"
{...props}
>
{children}
</code>
) : (
<code className="block text-foreground text-sm" {...props}>
{children}
</code>
);
},
table: ({ children, ...props }) => (
<div className="my-8 w-full overflow-x-auto">
<table
className="min-w-full divide-y divide-border border border-border"
{...props}
>
{children}
</table>
</div>
),
thead: ({ children, ...props }) => (
<thead className="bg-muted" {...props}>
{children}
</thead>
),
tbody: ({ children, ...props }) => (
<tbody className="divide-y divide-border bg-card" {...props}>
{children}
</tbody>
),
tr: ({ children, ...props }) => (
<tr className="hover:bg-accent" {...props}>
{children}
</tr>
),
th: ({ children, ...props }) => (
<th
className="px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider border-r last:border-r-0"
{...props}
>
{children}
</th>
),
td: ({ children, ...props }) => (
<td
className="px-6 py-4 whitespace-nowrap text-sm text-muted-foreground border-r last:border-r-0"
{...props}
>
{children}
</td>
),
blockquote: ({ children, ...props }) => (
<blockquote
className="border-l-4 border-primary pl-4 my-4 italic text-muted-foreground bg-muted py-2 rounded-r-lg"
{...props}
>
{children}
</blockquote>
),
ul: ({ children, ...props }) => (
<ul
className="list-disc list-outside ml-6 my-6 space-y-2 text-foreground"
{...props}
>
{children}
</ul>
),
ol: ({ children, ...props }) => (
<ol
className="list-decimal list-outside ml-6 my-6 space-y-2 text-foreground"
{...props}
>
{children}
</ol>
),
li: ({ children, ...props }) => (
<li className="pl-2 leading-relaxed" {...props}>
{children}
</li>
),
mermaid: Mermaid, // Use the defined Mermaid component
};