import type { AnchorHTMLAttributes, ComponentProps } from 'react'; import { Link } from 'react-router'; import defaultMdxComponents from 'fumadocs-ui/mdx'; import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock'; import { ImageZoom } from 'fumadocs-ui/components/image-zoom'; import { config } from 'virtual:seemore/config'; import { isExternalHref, stripBase } from '../../shared/base.js'; import { feature } from '../lib/features.js'; import { D2 } from './D2.js'; import { Mermaid } from './Mermaid.js'; import { Pdf } from './Pdf.js'; /** * Internal links go through React Router so navigation stays client-side. * * remark rewrote content links to *based* hrefs, and React Router re-applies the * basename itself, so the base is stripped here to keep it from appearing twice. * * MDX only substitutes the `a` override for links written as Markdown syntax — a literal * `` tag in an `.mdx` file compiles straight to a DOM element and never sees this * component. `` is exposed alongside it (below, in `mdxComponents`) for exactly that * case: a hand-styled internal link that still needs to navigate through the router. */ function MdxLink({ href = '', children, ...props }: AnchorHTMLAttributes) { if (isExternalHref(href)) { const external = /^[a-z][a-z0-9+.-]*:|^\/\//i.test(href); return ( {children} ); } return ( {children} ); } function isPdf(src: string | undefined): src is string { if (typeof src !== 'string') return false; // A small PDF is inlined by the bundler, so the extension is gone and the mime type is // the only thing left to go on. return /\.pdf(?:[?#].*)?$/i.test(src) || src.startsWith('data:application/pdf'); } /** Sibling assets: images inline (click-to-zoom, unless switched off), PDFs in a viewer. */ function MdxImage({ src, alt, ...props }: ComponentProps<'img'>) { const source = typeof src === 'string' ? src : undefined; if (isPdf(source)) { return ; } if (feature('content.image.zoom')) { return ; } const Image = defaultMdxComponents.img; return {alt}; } /** * fumadocs' own `pre`, with the site-wide copy flag folded in. * * A fence's `noCopy` reaches us as `allowCopy="false"` — `rehype-code` rewrites the meta — * so passing the prop straight through keeps per-block control working, and the flag only * decides what every other fence does. */ function MdxPre({ allowCopy, children, ...props }: ComponentProps) { return (
{children}
); } export const mdxComponents = { ...defaultMdxComponents, a: MdxLink, pre: MdxPre, // For a hand-written `` in `.mdx` content — MDX doesn't route those through `a` above, // so `` is the escape hatch when a link needs its own classes or layout. Link: MdxLink, img: MdxImage, // `remark-mdx-mermaid` rewrites ```mermaid fences to , but supplies no // component of its own — this is ours. Mermaid, // Our own `remarkSeemoreD2` does the same for ```d2 fences. D2, Pdf, };