Skip to content

Commit 21a63ac

Browse files
committed
packages/ui: Add markdown-renderer
1 parent d25d067 commit 21a63ac

File tree

17 files changed

+314
-742
lines changed

17 files changed

+314
-742
lines changed

apps/dashboard/knip.json

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
{
2-
"$schema": "https://unpkg.com/knip@5/schema.json",
3-
"ignore": [
4-
"src/@/components/ui/**",
5-
"src/@/components/misc/AnnouncementBanner.tsx",
6-
"src/@/components/cmd-k-search/index.tsx",
7-
"src/@/lib/search.ts"
8-
],
9-
"ignoreBinaries": ["only-allow"],
10-
"ignoreDependencies": [
11-
"@thirdweb-dev/service-utils",
12-
"@thirdweb-dev/vault-sdk",
13-
"thirdweb",
14-
"@types/color",
15-
"fast-xml-parser",
16-
"@workspace/ui",
17-
"tailwindcss-animate",
18-
"@radix-ui/react-tooltip",
19-
"shiki"
20-
],
21-
"next": true,
22-
"project": ["src/**"]
2+
"$schema": "https://unpkg.com/knip@5/schema.json",
3+
"ignore": [
4+
"src/@/components/ui/**",
5+
"src/@/components/misc/AnnouncementBanner.tsx",
6+
"src/@/components/cmd-k-search/index.tsx",
7+
"src/@/lib/search.ts"
8+
],
9+
"ignoreBinaries": ["only-allow"],
10+
"ignoreDependencies": [
11+
"@thirdweb-dev/service-utils",
12+
"@thirdweb-dev/vault-sdk",
13+
"thirdweb",
14+
"@types/color",
15+
"fast-xml-parser",
16+
"@workspace/ui",
17+
"tailwindcss-animate",
18+
"@radix-ui/react-tooltip",
19+
"shiki",
20+
"react-children-utilities",
21+
"react-markdown",
22+
"remark-gfm"
23+
],
24+
"next": true,
25+
"project": ["src/**"]
2326
}
Lines changed: 1 addition & 225 deletions
Original file line numberDiff line numberDiff line change
@@ -1,225 +1 @@
1-
import { onlyText } from "react-children-utilities";
2-
import ReactMarkdown from "react-markdown";
3-
import remarkGfm from "remark-gfm";
4-
import { CodeClient } from "@/components/ui/code/code.client";
5-
import { PlainTextCodeBlock } from "@/components/ui/code/plaintext-code";
6-
import { InlineCode } from "@/components/ui/inline-code";
7-
import {
8-
Table,
9-
TableBody,
10-
TableCell,
11-
TableContainer,
12-
TableHead,
13-
TableHeader,
14-
TableRow,
15-
} from "@/components/ui/table";
16-
import { UnderlineLink } from "@/components/ui/UnderlineLink";
17-
import { cn } from "@/lib/utils";
18-
19-
export const MarkdownRenderer: React.FC<{
20-
markdownText: string;
21-
className?: string;
22-
code?: {
23-
disableCodeHighlight?: boolean;
24-
ignoreFormattingErrors?: boolean;
25-
className?: string;
26-
};
27-
inlineCode?: {
28-
className?: string;
29-
};
30-
p?: {
31-
className?: string;
32-
};
33-
li?: {
34-
className?: string;
35-
};
36-
skipHtml?: boolean;
37-
}> = (markdownProps) => {
38-
const { markdownText, className, code } = markdownProps;
39-
const commonHeadingClassName = "mb-2 leading-5 font-semibold tracking-tight";
40-
41-
return (
42-
<div className={className}>
43-
<ReactMarkdown
44-
components={{
45-
a: (props) => (
46-
<UnderlineLink
47-
href={props.href ?? "#"}
48-
rel="noopener noreferrer"
49-
target="_blank"
50-
{...cleanedProps(props)}
51-
className="mt-4"
52-
/>
53-
),
54-
55-
code: ({ ...props }) => {
56-
const codeStr = onlyText(props.children);
57-
58-
if (props?.className || codeStr.length > 100) {
59-
if (code?.disableCodeHighlight || !props.className) {
60-
return (
61-
<div className="my-4">
62-
{/* @ts-expect-error - TODO: fix this */}
63-
<PlainTextCodeBlock
64-
{...cleanedProps(props)}
65-
className={markdownProps.code?.className}
66-
code={onlyText(props.children).trim()}
67-
/>
68-
</div>
69-
);
70-
}
71-
const language = props.className.replace("language-", "");
72-
return (
73-
<div className="my-4">
74-
<CodeClient
75-
// @ts-expect-error - TODO: fix this
76-
lang={language}
77-
{...cleanedProps(props)}
78-
className={markdownProps.code?.className}
79-
code={onlyText(props.children).trim()}
80-
ignoreFormattingErrors={code?.ignoreFormattingErrors}
81-
/>
82-
</div>
83-
);
84-
}
85-
86-
return (
87-
<InlineCode
88-
className={markdownProps.inlineCode?.className}
89-
code={onlyText(props.children).trim()}
90-
/>
91-
);
92-
},
93-
h1: (props) => (
94-
<h2
95-
className={cn(
96-
commonHeadingClassName,
97-
"mb-3 border-dashed border-b pb-2 text-xl md:text-2xl",
98-
)}
99-
{...cleanedProps(props)}
100-
/>
101-
),
102-
103-
h2: (props) => (
104-
<h3
105-
{...cleanedProps(props)}
106-
className={cn(
107-
commonHeadingClassName,
108-
"mt-8 mb-3 border-dashed border-b pb-2 text-lg md:text-xl",
109-
)}
110-
/>
111-
),
112-
113-
h3: (props) => (
114-
<h4
115-
{...cleanedProps(props)}
116-
className={cn(
117-
commonHeadingClassName,
118-
"mt-4 text-base md:text-lg",
119-
)}
120-
/>
121-
),
122-
123-
h4: (props) => (
124-
<h5
125-
{...cleanedProps(props)}
126-
className={cn(commonHeadingClassName, "mt-4 text-lg")}
127-
/>
128-
),
129-
130-
h5: (props) => (
131-
<h6
132-
{...cleanedProps(props)}
133-
className={cn(commonHeadingClassName, "mt-4 text-lg")}
134-
/>
135-
),
136-
137-
h6: (props) => (
138-
<p
139-
{...cleanedProps(props)}
140-
className={cn(commonHeadingClassName, "mt-4 text-lg")}
141-
/>
142-
),
143-
144-
hr: (props) => (
145-
<hr {...cleanedProps(props)} className="my-5 bg-border" />
146-
),
147-
li: ({ children: c, ...props }) => (
148-
<li
149-
className={cn(
150-
"text-muted-foreground leading-relaxed [&>p]:m-0",
151-
markdownProps.li?.className,
152-
)}
153-
{...cleanedProps(props)}
154-
>
155-
{c}
156-
</li>
157-
),
158-
ol: (props) => (
159-
<ol
160-
className="mb-4 list-outside list-decimal pl-4 space-y-2 [&>li]:first:mt-2"
161-
{...cleanedProps(props)}
162-
/>
163-
),
164-
165-
p: (props) => (
166-
<p
167-
className={cn(
168-
"mb-3 text-muted-foreground leading-7",
169-
markdownProps.p?.className,
170-
)}
171-
{...cleanedProps(props)}
172-
/>
173-
),
174-
strong(props) {
175-
return <strong className="font-medium" {...cleanedProps(props)} />;
176-
},
177-
178-
table: (props) => (
179-
<div className="mb-6">
180-
<TableContainer>
181-
<Table {...cleanedProps(props)} />
182-
</TableContainer>
183-
</div>
184-
),
185-
tbody: (props) => <TableBody {...cleanedProps(props)} />,
186-
187-
td: (props) => (
188-
<TableCell {...cleanedProps(props)} className="text-left" />
189-
),
190-
191-
th: ({ children: c, ...props }) => (
192-
<TableHead
193-
{...cleanedProps(props)}
194-
className="text-left text-muted-foreground"
195-
>
196-
{c}
197-
</TableHead>
198-
),
199-
thead: (props) => <TableHeader {...cleanedProps(props)} />,
200-
tr: (props) => <TableRow {...cleanedProps(props)} />,
201-
ul: (props) => {
202-
return (
203-
<ul
204-
className="mb-4 list-outside list-disc pl-4 space-y-2 [&>li]:first:mt-2"
205-
{...cleanedProps(props)}
206-
/>
207-
);
208-
},
209-
}}
210-
remarkPlugins={[remarkGfm]}
211-
skipHtml={markdownProps.skipHtml}
212-
>
213-
{markdownText}
214-
</ReactMarkdown>
215-
</div>
216-
);
217-
};
218-
219-
function cleanedProps<T extends object & { node?: unknown }>(
220-
props: T,
221-
): Omit<T, "node"> {
222-
// biome-ignore lint/correctness/noUnusedVariables: EXPECTED
223-
const { node, ...rest } = props;
224-
return rest;
225-
}
1+
export { MarkdownRenderer } from "@workspace/ui/components/markdown-renderer";

apps/dashboard/src/@/components/chat/CustomChats.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,15 @@ function StyledMarkdownRenderer(props: {
413413
}) {
414414
return (
415415
<MarkdownRenderer
416-
className="[&>*:first-child]:mt-0 [&>*:first-child]:border-none [&>*:first-child]:pb-0 [&>*:last-child]:mb-0"
416+
className="text-sm text-foreground [&>*:first-child]:mt-0 [&>*:first-child]:border-none [&>*:first-child]:pb-0 [&>*:last-child]:mb-0 leading-relaxed"
417417
code={{
418-
className: "bg-card",
419418
ignoreFormattingErrors: true,
420419
}}
421420
inlineCode={{ className: "border-none" }}
421+
li={{ className: "text-foreground leading-relaxed" }}
422422
markdownText={props.text}
423423
p={{
424-
className: props.type === "assistant" ? "" : "leading-normal",
424+
className: "text-foreground leading-relaxed",
425425
}}
426426
skipHtml
427427
/>
Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1 @@
1-
import Link from "next/link";
2-
import { cn } from "../../lib/utils";
3-
4-
type LinkProps = React.ComponentProps<typeof Link>;
5-
6-
export function UnderlineLink(props: LinkProps) {
7-
return (
8-
<Link
9-
{...props}
10-
className={cn(
11-
"underline decoration-muted-foreground/50 decoration-dotted underline-offset-[5px] hover:text-foreground hover:decoration-foreground hover:decoration-solid",
12-
props.className,
13-
)}
14-
/>
15-
);
16-
}
1+
export { UnderlineLink } from "@workspace/ui/components/UnderlineLink";

apps/playground-web/knip.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
"@workspace/ui",
77
"tailwindcss-animate",
88
"@radix-ui/react-tooltip",
9-
"prettier"
9+
"prettier",
10+
"react-children-utilities",
11+
"react-markdown",
12+
"remark-gfm"
1013
],
1114
"next": true,
1215
"project": ["src/**"]

0 commit comments

Comments
 (0)