authorgravatar for 206951365+cursor[bot]@users.noreply.github.comcursor[bot] <206951365+cursor[bot]@users.noreply.github.com> 2026-05-04 09:38:17-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-05-04 09:38:17-07:00
log623e471a0230e9aba289c74a2120bbe91250949a
treeb781ed2c7ca720c7640e4cbf30b5fc19c5374e96
parent91a03e074751e9dc732d0dddcd7b3a291caba34f
signature Signed by PGP key B5690EEEBB952194

Fix markdown highlight render stability (#2479)

Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>

2 files changed, 30 insertions(+), 2 deletions(-)

apps/web/src/components/ChatMarkdown.tsx+26
......@@ -211,6 +211,32 @@ function SuspenseShikiCodeBlock({
211211 );
212212 }
213213
214 return (
215 <UncachedShikiCodeBlock
216 code={code}
217 language={language}
218 themeName={themeName}
219 cacheKey={cacheKey}
220 isStreaming={isStreaming}
221 />
222 );
223}
224
225interface UncachedShikiCodeBlockProps {
226 code: string;
227 language: string;
228 themeName: DiffThemeName;
229 cacheKey: string;
230 isStreaming: boolean;
231}
232
233function UncachedShikiCodeBlock({
234 code,
235 language,
236 themeName,
237 cacheKey,
238 isStreaming,
239}: UncachedShikiCodeBlockProps) {
214240 const highlighter = use(getHighlighterPromise(language));
215241 const highlightedHtml = useMemo(() => {
216242 try {
apps/web/src/components/chat/MessagesTimeline.tsx+4-2
......@@ -87,6 +87,8 @@ interface TimelineRowSharedState {
8787}
8888
8989const TimelineRowCtx = createContext<TimelineRowSharedState>(null!);
90const TIMELINE_LIST_HEADER = <div className="h-3 sm:h-4" />;
91const TIMELINE_LIST_FOOTER = <div className="h-3 sm:h-4" />;
9092
9193// ---------------------------------------------------------------------------
9294// Props (public API)
......@@ -261,8 +263,8 @@ export const MessagesTimeline = memo(function MessagesTimeline({
261263 maintainVisibleContentPosition
262264 onScroll={handleScroll}
263265 className="h-full overflow-x-hidden overscroll-y-contain px-3 sm:px-5"
264 ListHeaderComponent={<div className="h-3 sm:h-4" />}
265 ListFooterComponent={<div className="h-3 sm:h-4" />}
266 ListHeaderComponent={TIMELINE_LIST_HEADER}
267 ListFooterComponent={TIMELINE_LIST_FOOTER}
266268 />
267269 </TimelineRowCtx.Provider>
268270 );