60 lines
2.1 KiB
TypeScript
60 lines
2.1 KiB
TypeScript
import { Link } from '@tanstack/react-router'
|
|
import Markdown from 'react-markdown'
|
|
import rehypeRaw from 'rehype-raw'
|
|
import rehypeSanitize from 'rehype-sanitize'
|
|
import remarkGfm from 'remark-gfm'
|
|
|
|
interface Props {
|
|
children: string
|
|
}
|
|
|
|
export default function Mdown({ children }: Props) {
|
|
return (
|
|
<Markdown
|
|
remarkPlugins={[remarkGfm]}
|
|
rehypePlugins={[rehypeRaw, rehypeSanitize]}
|
|
components={{
|
|
ul(props) {
|
|
const { node, ...rest } = props
|
|
return <ul className="list-disc list-inside" {...rest} />
|
|
},
|
|
li(props) {
|
|
const { node, ...rest } = props
|
|
return <li className="pl-5" {...rest} />
|
|
},
|
|
a(props) {
|
|
const { node, ...rest } = props
|
|
const classes = 'text-sky-600 underline'
|
|
if (rest.href?.startsWith('dl:')) {
|
|
let parts = rest.href.split('/')
|
|
return (
|
|
<a
|
|
className={classes}
|
|
href={rest.href.replace('dl:', '')}
|
|
download={parts[parts.length - 1]}
|
|
{...rest}
|
|
/>
|
|
)
|
|
}
|
|
if (rest.href?.startsWith('/public')) {
|
|
return (
|
|
<a className={classes} target="_blank" {...rest} />
|
|
)
|
|
}
|
|
if (rest.href?.startsWith('/')) {
|
|
return (
|
|
<Link
|
|
className={classes}
|
|
to={rest.href}
|
|
{...rest}
|
|
/>
|
|
)
|
|
}
|
|
return <a className={classes} {...rest} />
|
|
},
|
|
}}
|
|
>
|
|
{children}
|
|
</Markdown>
|
|
)
|
|
}
|