Preserve markdown selection during re-renders

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-06-16 10:02:03 +00:00
1 parent 284508e54a
commit 57705f6b56
2 files changed
+31 -2

No files matched your search

@@ -84,4 +84,31 @@ describe("MarkdownBody re-render stability (PAP-10767)", () => {
expect(codeAfter).toBe(codeBefore);
expect(anchorAfter).toBe(anchorBefore);
});
it("preserves text selection across a parent re-render with unchanged props", () => {
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
flushSync(() => root?.render(tree(SAMPLE, queryClient)));
const paragraph = container.querySelector("p");
const textNode = paragraph?.firstChild;
expect(textNode?.nodeType).toBe(Node.TEXT_NODE);
const range = document.createRange();
range.setStart(textNode!, 0);
range.setEnd(textNode!, "Some text".length);
const selection = window.getSelection();
selection?.removeAllRanges();
selection?.addRange(range);
expect(selection?.toString()).toBe("Some text");
flushSync(() => root?.render(tree(SAMPLE, queryClient)));
expect(window.getSelection()?.toString()).toBe("Some text");
});
});
+4 -2
View File
@@ -1,4 +1,4 @@
import { isValidElement, useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode } from "react";
import { isValidElement, memo, useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode } from "react";
import { useQuery } from "@tanstack/react-query";
import { Check, Copy, ExternalLink, Github, WrapText } from "lucide-react";
import Markdown, { defaultUrlTransform, type Components, type Options } from "react-markdown";
@@ -563,7 +563,7 @@ function MermaidDiagramBlock({ source, darkMode }: { source: string; darkMode: b
);
}
export function MarkdownBody({
function MarkdownBodyImpl({
children,
className,
style,
@@ -778,3 +778,5 @@ export function MarkdownBody({
</div>
);
}
export const MarkdownBody = memo(MarkdownBodyImpl);