feat: add markdown component styling for blockquotes, code, tables, images
This commit is contained in:
parent
8fff67caf3
commit
9dfbbe71e8
2 changed files with 114 additions and 0 deletions
|
|
@ -48,6 +48,87 @@ p { font-size: 1rem; line-height: 1.6; color: var(--foreground); }
|
|||
.markdown-content ol { padding-left: 1.25rem; list-style: decimal; }
|
||||
.markdown-content a { text-decoration: underline; }
|
||||
|
||||
/* Markdown blockquote */
|
||||
.markdown-blockquote {
|
||||
border-left: 4px solid var(--color-green);
|
||||
padding: 0.75rem 1.25rem;
|
||||
margin: 1.25rem 0;
|
||||
background: rgba(0, 106, 61, 0.05);
|
||||
font-style: italic;
|
||||
color: var(--foreground);
|
||||
}
|
||||
.markdown-blockquote p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Markdown code */
|
||||
.markdown-code-inline {
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
padding: 0.125rem 0.375rem;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 0.9em;
|
||||
color: var(--color-red);
|
||||
}
|
||||
.markdown-pre {
|
||||
background: #f5f5f5;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
overflow-x: auto;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.markdown-pre code {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
/* Markdown table */
|
||||
.markdown-table-wrapper {
|
||||
overflow-x: auto;
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
.markdown-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
.markdown-table th,
|
||||
.markdown-table td {
|
||||
padding: 0.75rem 1rem;
|
||||
text-align: left;
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
.markdown-table th {
|
||||
background: rgba(0, 106, 61, 0.08);
|
||||
font-weight: 700;
|
||||
color: var(--foreground);
|
||||
}
|
||||
.markdown-table tr:nth-child(even) {
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
.markdown-table tr:hover {
|
||||
background: rgba(0, 106, 61, 0.03);
|
||||
}
|
||||
|
||||
/* Markdown horizontal rule */
|
||||
.markdown-hr {
|
||||
border: none;
|
||||
border-top: 2px solid var(--color-border);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
/* Markdown images */
|
||||
.markdown-img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 8px;
|
||||
margin: 1.25rem 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Layout utilities */
|
||||
.container {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"use client";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import type { Components } from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||
|
|
@ -24,11 +25,43 @@ export function MarkdownRenderer({ contentPath, onHeadings }: MarkdownRendererPr
|
|||
})();
|
||||
}, [contentPath, onHeadings]);
|
||||
|
||||
const components: Components = {
|
||||
blockquote: ({ children, ...props }) => (
|
||||
<blockquote className="markdown-blockquote" {...props}>
|
||||
{children}
|
||||
</blockquote>
|
||||
),
|
||||
code: ({ inline, className, children, ...props }: any) => {
|
||||
if (inline) {
|
||||
return <code className="markdown-code-inline" {...props}>{children}</code>;
|
||||
}
|
||||
return (
|
||||
<pre className="markdown-pre">
|
||||
<code className={className} {...props}>
|
||||
{children}
|
||||
</code>
|
||||
</pre>
|
||||
);
|
||||
},
|
||||
table: ({ children, ...props }) => (
|
||||
<div className="markdown-table-wrapper">
|
||||
<table className="markdown-table" {...props}>
|
||||
{children}
|
||||
</table>
|
||||
</div>
|
||||
),
|
||||
hr: (props) => <hr className="markdown-hr" {...props} />,
|
||||
img: ({ src, alt, ...props }) => (
|
||||
<img src={src} alt={alt || ""} className="markdown-img" loading="lazy" {...props} />
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<article className="markdown-content" aria-label="Conteúdo">
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
rehypePlugins={[rehypeSlug, [rehypeAutolinkHeadings, { behavior: "wrap" }]]}
|
||||
components={components}
|
||||
>
|
||||
{source}
|
||||
</ReactMarkdown>
|
||||
|
|
|
|||
Loading…
Reference in a new issue