Skip to content

Commit 421dc74

Browse files
committed
feat(markdown): optimize markdown render
1 parent a4b8d62 commit 421dc74

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

.changes/optimize-markdown.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@matechat/react": patch:feat
3+
---
4+
5+
Optimize markdown component in `Bubble`, customize link, heading and code. Support copy button for code blocks.

src/bubble.tsx

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,68 @@ export function Bubble({
149149
<Markdown
150150
remarkPlugins={[remarkGfm, remarkMath]}
151151
components={{
152+
h1(props) {
153+
const { children, className, node: _node, ...rest } = props;
154+
return (
155+
<h1
156+
{...rest}
157+
className={clsx("my-3 text-2xl font-bold", className)}
158+
>
159+
{children}
160+
</h1>
161+
);
162+
},
163+
h2(props) {
164+
const { children, className, node: _node, ...rest } = props;
165+
return (
166+
<h2
167+
{...rest}
168+
className={clsx("my-2 text-xl font-bold", className)}
169+
>
170+
{children}
171+
</h2>
172+
);
173+
},
174+
h3(props) {
175+
const { children, className, node: _node, ...rest } = props;
176+
return (
177+
<h3
178+
{...rest}
179+
className={clsx("my-1 text-lg font-bold", className)}
180+
>
181+
{children}
182+
</h3>
183+
);
184+
},
152185
code(props) {
153186
const { children, className, ref: _ref, ...rest } = props;
154187
const match = /language-(\w+)/.exec(className || "");
188+
189+
const [copied, setCopied] = useState(false);
190+
const handleCopy = () => {
191+
navigator.clipboard.writeText(String(children).replace(/\n$/, ''));
192+
setCopied(true);
193+
setTimeout(() => setCopied(false), 2000);
194+
};
195+
155196
return match ? (
156-
<div className="w-full overflow-x-auto border border-gray-300 dark:border-gray-700 bg-gray-100 dark:bg-gray-800 rounded-lg">
197+
<div
198+
className={clsx(
199+
"w-full overflow-x-auto rounded-lg",
200+
"bg-gray-50 dark:bg-gray-800",
201+
)}
202+
>
203+
<div className="inline-flex w-full justify-between bg-gray-100 p-2">
204+
<div className="px-2 py-1 text-xs text-gray-900 dark:text-gray-400">
205+
{match[1]}
206+
</div>
207+
<div
208+
className="px-2 py-1 text-xs text-gray-900 dark:text-gray-400 cursor-pointer"
209+
onClick={handleCopy}
210+
>
211+
{copied ? "Copied" : "Copy"}
212+
</div>
213+
</div>
157214
<SyntaxHighlighter
158215
{...rest}
159216
PreTag="div"
@@ -177,11 +234,45 @@ export function Bubble({
177234
</SyntaxHighlighter>
178235
</div>
179236
) : (
180-
<code {...rest} className={className}>
237+
<code
238+
{...rest}
239+
className={clsx(
240+
"rounded-md px-1 py-0.5 text-[85%]",
241+
"bg-gray-100 dark:bg-gray-800",
242+
)}
243+
>
181244
{children}
182245
</code>
183246
);
184247
},
248+
blockquote(props) {
249+
const { children, className, ...rest } = props;
250+
return (
251+
<blockquote
252+
{...rest}
253+
className={clsx(
254+
"border-l-4 border-gray-300 pl-4 italic",
255+
className,
256+
)}
257+
>
258+
{children}
259+
</blockquote>
260+
);
261+
},
262+
a(props) {
263+
const { children, className, ref: _ref, ...rest } = props;
264+
return (
265+
<a
266+
{...rest}
267+
className={clsx(
268+
"text-blue-600 dark:text-blue-400 hover:underline underline-offset-1",
269+
className,
270+
)}
271+
>
272+
{children}
273+
</a>
274+
);
275+
},
185276
}}
186277
>
187278
{text}

src/list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export function List({
7878
}
7979
>
8080
<div
81-
data-solt="list-label"
81+
data-slot="list-label"
8282
className="px-3 py-2 bg-gray-100 font-medium text-sm flex items-center gap-2"
8383
>
8484
{optionGroupTemplate

0 commit comments

Comments
 (0)