Skip to content

Commit

Permalink
fix: rehype inject filesv2 for estree (#2081)
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity authored Jan 25, 2025
1 parent e043c41 commit 22c3e70
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 19 deletions.
5 changes: 4 additions & 1 deletion packages/fern-docs/mdx/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export type { MdxJsxAttribute } from "mdast-util-mdx";
export type {
MdxJsxAttribute,
MdxJsxExpressionAttribute,
} from "mdast-util-mdx";
export type { MDXComponents } from "mdx/types";
export type { PluggableList } from "unified";
export {
Expand Down
1 change: 1 addition & 0 deletions packages/fern-docs/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"colorjs.io": "^0.5.2",
"es-toolkit": "^1.27.0",
"esbuild": "0.24.2",
"estree-walker": "^3.0.3",
"fastdom": "^1.0.12",
"framer-motion": "^11.2.4",
"github-slugger": "^2.0.0",
Expand Down
5 changes: 4 additions & 1 deletion packages/fern-docs/ui/src/components/FernImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export const FernImage = forwardRef<

// nextjs requires a strict allowlist of hosts for <Image>
// so we'll fall back to <img> if the host is not in the allowlist (or if no custom loader is provided)
if ((!host || !NEXT_IMAGE_HOSTS.includes(host)) && !loader) {
if (
((!host || !NEXT_IMAGE_HOSTS.includes(host)) && !loader) ||
(!width && !height)
) {
return (
<img
ref={ref}
Expand Down
46 changes: 45 additions & 1 deletion packages/fern-docs/ui/src/mdx/plugins/rehype-files.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import type { Hast } from "@fern-docs/mdx";
import type {
Hast,
MdxJsxAttribute,
MdxJsxExpressionAttribute,
} from "@fern-docs/mdx";
import {
isMdxJsxAttribute,
isMdxJsxElementHast,
mdxJsxAttributeToString,
visit,
} from "@fern-docs/mdx";
import { walk } from "estree-walker";

import type { ImageData } from "../../atoms/types";

export interface RehypeFilesOptions {
Expand Down Expand Up @@ -121,5 +127,43 @@ export function rehypeFiles(
}
}
});

// additional support for jsx attributes that are nested inside of jsx attributes
visit(tree, (node) => {
if (isMdxJsxElementHast(node)) {
node.attributes.forEach((attr) => {
const estree = getEstree(attr);
if (estree == null) {
return;
}
walk(estree, {
enter(node) {
if (node.type === "Literal" && typeof node.value === "string") {
// TODO: if the replaced src is a Image (contains width and height), we need to add them to the parent JSX root somehow.
// for example: <Card icon={<img src="fileId" />} /> -> <Card icon={<img src="replacedImgUrl" width={w} height={h} />} />
// currently, we cannot leverage NextJS Image Optimization for this edge case.
node.value =
options.replaceSrc?.(node.value)?.src ?? node.value;
}
},
});
});
}
});
};
}

function getEstree(attr: MdxJsxAttribute | MdxJsxExpressionAttribute) {
if (
attr.type === "mdxJsxAttribute" &&
attr.value &&
typeof attr.value !== "string" &&
attr.value.type === "mdxJsxAttributeValueExpression" &&
attr.value.data?.estree
) {
return attr.value.data?.estree;
} else if (attr.type === "mdxJsxExpressionAttribute" && attr.data?.estree) {
return attr.data?.estree;
}
return null;
}
25 changes: 9 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 22c3e70

Please sign in to comment.