import ReactMarkdown, { type Components } from "react-markdown"; import remarkGfm from "remark-gfm"; /** * Server-rendered markdown for SOPs and the SOP README. * * The WFDASH app doesn't depend on `@tailwindcss/typography`, so we * hand-style the elements that show up in the SOPs (headings, * paragraphs, lists, tables, code blocks, blockquotes, hr). * * The `components` map below is the single source of truth for those * styles. If a new markdown shape shows up in an SOP, add a class * here rather than introducing the typography plugin. */ export function Markdown({ children }: { children: string }) { return ( {children} ); } const components: Components = { h1: ({ children, ...props }) => (

{children}

), h2: ({ children, ...props }) => (

{children}

), h3: ({ children, ...props }) => (

{children}

), h4: ({ children, ...props }) => (

{children}

), p: ({ children, ...props }) => (

{children}

), ul: ({ children, ...props }) => ( ), ol: ({ children, ...props }) => (
    {children}
), li: ({ children, ...props }) => (
  • {children}
  • ), a: ({ children, href, ...props }) => ( {children} ), blockquote: ({ children, ...props }) => (
    {children}
    ), hr: (props) => (
    ), // GFM tables. The Markdown plugin emits these as a `table` element // with thead/tbody/tr/th/td children. Wrap in a scrollable container // so wide KPI tables don't blow out the layout. table: ({ children, ...props }) => (
    {children}
    ), thead: ({ children, ...props }) => ( {children} ), tbody: ({ children, ...props }) => ( {children} ), tr: ({ children, ...props }) => ( {children} ), th: ({ children, ...props }) => ( {children} ), td: ({ children, ...props }) => ( {children} ), code: ({ children, className, ...props }) => { // `react-markdown` puts fenced code blocks in a
     pair
        // and inline code in a bare . The presence of a `className`
        // (set by `react-markdown` for fenced blocks, e.g. "language-ts")
        // is the discriminator. For inline code we just style the chip.
        const isBlock = typeof className === "string" && className.length > 0;
        if (isBlock) {
          return (
            
              {children}
            
          );
        }
        return (
          
            {children}
          
        );
      },
      pre: ({ children, ...props }) => (
        
          {children}
        
    ), strong: ({ children, ...props }) => ( {children} ), em: ({ children, ...props }) => ( {children} ), input: ({ type, checked, disabled, ...props }) => { // GFM task-list checkboxes render as disabled checkboxes. Just // pass them through — we don't need a custom checkbox component, // the default browser style is fine and conveys "completed task". if (type === "checkbox") { return ( ); } return ; }, };