|
| 1 | +// --------------------------------------------------------------------------- |
| 2 | +// JSX runtime values needed by runSync |
| 3 | +// --------------------------------------------------------------------------- |
| 4 | + |
| 5 | +// We re-import the jsx-runtime exports as opaque values so we can pass them |
| 6 | +// through to runSync without running into ReScript's monomorphisation of |
| 7 | +// the polymorphic `React.jsx` / `React.jsxs` signatures. |
| 8 | +/** |
| 9 | + * MdxContent — renders compiled MDX content as a React component. |
| 10 | + * |
| 11 | + * Uses `runSync` from `@mdx-js/mdx` to evaluate compiled MDX (produced by |
| 12 | + * `MdxFile.compileMdx`) and renders the result with a shared component map. |
| 13 | + */ |
| 14 | +type jsxRuntimeValue |
| 15 | + |
| 16 | +@module("react/jsx-runtime") external fragment: jsxRuntimeValue = "Fragment" |
| 17 | +@module("react/jsx-runtime") external jsx: jsxRuntimeValue = "jsx" |
| 18 | +@module("react/jsx-runtime") external jsxs: jsxRuntimeValue = "jsxs" |
| 19 | + |
| 20 | +@val @scope(("import", "meta")) external importMetaUrl: string = "url" |
| 21 | + |
| 22 | +// --------------------------------------------------------------------------- |
| 23 | +// @mdx-js/mdx runSync binding |
| 24 | +// --------------------------------------------------------------------------- |
| 25 | + |
| 26 | +type runOptions = { |
| 27 | + @as("Fragment") fragment: jsxRuntimeValue, |
| 28 | + jsx: jsxRuntimeValue, |
| 29 | + jsxs: jsxRuntimeValue, |
| 30 | + baseUrl: string, |
| 31 | +} |
| 32 | + |
| 33 | +type mdxModule |
| 34 | + |
| 35 | +@module("@mdx-js/mdx") |
| 36 | +external runSync: (CompiledMdx.t, runOptions) => mdxModule = "runSync" |
| 37 | + |
| 38 | +@get external getDefault: mdxModule => React.component<{..}> = "default" |
| 39 | + |
| 40 | +let runOptions = { |
| 41 | + fragment, |
| 42 | + jsx, |
| 43 | + jsxs, |
| 44 | + baseUrl: importMetaUrl, |
| 45 | +} |
| 46 | + |
| 47 | +// --------------------------------------------------------------------------- |
| 48 | +// Shared MDX component map |
| 49 | +// --------------------------------------------------------------------------- |
| 50 | + |
| 51 | +let components = { |
| 52 | + // Standard HTML element overrides |
| 53 | + "a": Markdown.A.make, |
| 54 | + "blockquote": Markdown.Blockquote.make, |
| 55 | + "code": Markdown.Code.make, |
| 56 | + "h1": Markdown.H1.make, |
| 57 | + "h2": Markdown.H2.make, |
| 58 | + "h3": Markdown.H3.make, |
| 59 | + "h4": Markdown.H4.make, |
| 60 | + "h5": Markdown.H5.make, |
| 61 | + "hr": Markdown.Hr.make, |
| 62 | + "li": Markdown.Li.make, |
| 63 | + "ol": Markdown.Ol.make, |
| 64 | + "p": Markdown.P.make, |
| 65 | + "pre": Markdown.Pre.make, |
| 66 | + "strong": Markdown.Strong.make, |
| 67 | + "table": Markdown.Table.make, |
| 68 | + "th": Markdown.Th.make, |
| 69 | + "thead": Markdown.Thead.make, |
| 70 | + "td": Markdown.Td.make, |
| 71 | + "ul": Markdown.Ul.make, |
| 72 | + // Custom MDX components |
| 73 | + "Cite": Markdown.Cite.make, |
| 74 | + "CodeTab": Markdown.CodeTab.make, |
| 75 | + "Image": Markdown.Image.make, |
| 76 | + "Info": Markdown.Info.make, |
| 77 | + "Intro": Markdown.Intro.make, |
| 78 | + "UrlBox": Markdown.UrlBox.make, |
| 79 | + "Video": Markdown.Video.make, |
| 80 | + "Warn": Markdown.Warn.make, |
| 81 | + "CommunityContent": CommunityContent.make, |
| 82 | + "WarningTable": WarningTable.make, |
| 83 | + "Docson": DocsonLazy.make, |
| 84 | + "Suspense": React.Suspense.make, |
| 85 | +} |
| 86 | + |
| 87 | +// --------------------------------------------------------------------------- |
| 88 | +// React component |
| 89 | +// --------------------------------------------------------------------------- |
| 90 | + |
| 91 | +@react.component |
| 92 | +let make = (~compiledMdx: CompiledMdx.t) => { |
| 93 | + let element = React.useMemo(() => { |
| 94 | + let mdxModule = runSync(compiledMdx, runOptions) |
| 95 | + let content = getDefault(mdxModule) |
| 96 | + React.jsx(content, {"components": components}) |
| 97 | + }, [compiledMdx]) |
| 98 | + |
| 99 | + element |
| 100 | +} |
0 commit comments