markdown.tsx 900 B

123456789101112131415161718192021222324252627282930313233343536
  1. import { useMarked } from "../context/marked"
  2. import { ComponentProps, createResource, splitProps } from "solid-js"
  3. function strip(text: string): string {
  4. const wrappedRe = /^\s*<([A-Za-z]\w*)>\s*([\s\S]*?)\s*<\/\1>\s*$/
  5. const match = text.match(wrappedRe)
  6. return match ? match[2] : text
  7. }
  8. export function Markdown(
  9. props: ComponentProps<"div"> & {
  10. text: string
  11. class?: string
  12. classList?: Record<string, boolean>
  13. },
  14. ) {
  15. const [local, others] = splitProps(props, ["text", "class", "classList"])
  16. const marked = useMarked()
  17. const [html] = createResource(
  18. () => strip(local.text),
  19. async (markdown) => {
  20. return marked.parse(markdown)
  21. },
  22. )
  23. return (
  24. <div
  25. data-component="markdown"
  26. classList={{
  27. ...(local.classList ?? {}),
  28. [local.class ?? ""]: !!local.class,
  29. }}
  30. innerHTML={html()}
  31. {...others}
  32. />
  33. )
  34. }