Test Product · Anthony Lukach · Source Cooperative | Source CooperativeHello world
1import { Text, Heading, Link as RadixLink, Table } from "@radix-ui/themes";
2import { MarkdownAsync } from "react-markdown";
3import remarkGfm from "remark-gfm";
4import rehypeRaw from "rehype-raw";
5import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
6import rehypeStarryNight from "rehype-starry-night";
7import "@/styles/MarkdownViewer.css";
1import { Text, Heading, Link as RadixLink, Table } from "@radix-ui/themes";
2import { MarkdownAsync } from "react-markdown";
3import remarkGfm from "remark-gfm";
4import rehypeRaw from "rehype-raw";
5import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
6import rehypeStarryNight from "rehype-starry-night";
7import "@/styles/MarkdownViewer.css";
9interface MarkdownViewerProps {
13// Utility function to convert heading text to URL-friendly ID
14function generateHeadingId(text: string): string {
17 .replace(/[^\w\s-]/g, "") // Remove special characters except spaces and hyphens
18 .replace(/\s+/g, "-") // Replace spaces with hyphens
19 .replace(/-+/g, "-") // Replace multiple hyphens with single hyphen
23export async function MarkdownViewer({ content }: MarkdownViewerProps) {
24 if (typeof content !== "string") {
26 `MarkdownViewer expects string content, got ${typeof content}`
32 remarkPlugins={[remarkGfm]}
37 // Sanitization schema that allows images while maintaining security
41 ...defaultSchema.attributes,
42 img: ["src", "alt", "title", "width", "height"],
44 tagNames: [...(defaultSchema.tagNames || []), "img"],
50 h1: ({ children }) => (
51 <Heading size="8" mb="4" id={generateHeadingId(String(children))}>
55 h2: ({ children }) => (
56 <Heading size="7" mb="3" id={generateHeadingId(String(children))}>
60 h3: ({ children }) => (
61 <Heading size="6" mb="2" id={generateHeadingId(String(children))}>
65 h4: ({ children }) => (
66 <Heading size="5" mb="2" id={generateHeadingId(String(children))}>
70 h5: ({ children }) => (
71 <Heading size="4" mb="2" id={generateHeadingId(String(children))}>
75 h6: ({ children }) => (
76 <Heading size="3" mb="2" id={generateHeadingId(String(children))}>
80 p: ({ children }) => (
85 a: ({ href, children }) => (
86 <RadixLink href={href}>{children}</RadixLink>
88 table: ({ children }) => (
89 <Table.Root mb="3" variant="surface">
93 thead: ({ children }) => <Table.Header>{children}</Table.Header>,
94 tbody: ({ children }) => <Table.Body>{children}</Table.Body>,
95 tr: ({ children }) => <Table.Row>{children}</Table.Row>,
96 th: ({ children }) => (
97 <Table.ColumnHeaderCell>{children}</Table.ColumnHeaderCell>
99 td: ({ children }) => <Table.Cell>{children}</Table.Cell>,
9interface MarkdownViewerProps {
13// Utility function to convert heading text to URL-friendly ID
14function generateHeadingId(text: string): string {
17 .replace(/[^\w\s-]/g, "") // Remove special characters except spaces and hyphens
18 .replace(/\s+/g, "-") // Replace spaces with hyphens
19 .replace(/-+/g, "-") // Replace multiple hyphens with single hyphen
23export async function MarkdownViewer({ content }: MarkdownViewerProps) {
24 if (typeof content !== "string") {
26 `MarkdownViewer expects string content, got ${typeof content}`
32 remarkPlugins={[remarkGfm]}
37 // Sanitization schema that allows images while maintaining security
41 ...defaultSchema.attributes,
42 img: ["src", "alt", "title", "width", "height"],
44 tagNames: [...(defaultSchema.tagNames || []), "img"],
50 h1: ({ children }) => (
51 <Heading size="8" mb="4" id={generateHeadingId(String(children))}>
55 h2: ({ children }) => (
56 <Heading size="7" mb="3" id={generateHeadingId(String(children))}>
60 h3: ({ children }) => (
61 <Heading size="6" mb="2" id={generateHeadingId(String(children))}>
65 h4: ({ children }) => (
66 <Heading size="5" mb="2" id={generateHeadingId(String(children))}>
70 h5: ({ children }) => (
71 <Heading size="4" mb="2" id={generateHeadingId(String(children))}>
75 h6: ({ children }) => (
76 <Heading size="3" mb="2" id={generateHeadingId(String(children))}>
80 p: ({ children }) => (
85 a: ({ href, children }) => (
86 <RadixLink href={href}>{children}</RadixLink>
88 table: ({ children }) => (
89 <Table.Root mb="3" variant="surface">
93 thead: ({ children }) => <Table.Header>{children}</Table.Header>,
94 tbody: ({ children }) => <Table.Body>{children}</Table.Body>,
95 tr: ({ children }) => <Table.Row>{children}</Table.Row>,
96 th: ({ children }) => (
97 <Table.ColumnHeaderCell>{children}</Table.ColumnHeaderCell>
99 td: ({ children }) => <Table.Cell>{children}</Table.Cell>,