Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
improvement(ui): inline passthrough wrapper, add hydration guard
- Inline EnhancedMarkdownRenderer which became a trivial passthrough
  after removing useThrottledValue
- Add hydration guard to MarkdownRenderer to prevent replaying the
  entrance animation when mounting mid-stream with existing content
  • Loading branch information
emir-karabeg committed Apr 14, 2026
commit 170904af2a0d605777eff7a6be769eebbf4534c9
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { type HTMLAttributes, memo, type ReactNode, useMemo } from 'react'
import React, { type HTMLAttributes, memo, type ReactNode, useEffect, useMemo, useRef } from 'react'
import { Streamdown } from 'streamdown'
import 'streamdown/styles.css'
import { CopyCodeButton, Tooltip } from '@/components/emcn'
Expand Down Expand Up @@ -182,6 +182,14 @@ const MarkdownRenderer = memo(function MarkdownRenderer({
customLinkComponent?: typeof LinkWithPreview
isStreaming?: boolean
}) {
const hydratedStreamingRef = useRef(isStreaming && content.trim().length > 0)

useEffect(() => {
if (!isStreaming) {
hydratedStreamingRef.current = false
}
}, [isStreaming])

const components = useMemo(() => {
if (!customLinkComponent) {
return DEFAULT_COMPONENTS
Expand All @@ -196,7 +204,7 @@ const MarkdownRenderer = memo(function MarkdownRenderer({
<Streamdown
mode={isStreaming ? undefined : 'static'}
isAnimating={isStreaming}
animated={isStreaming}
animated={isStreaming && !hydratedStreamingRef.current}
components={components}
>
{processedContent}
Expand Down
12 changes: 1 addition & 11 deletions apps/sim/app/chat/components/message/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ export interface ChatMessage {
files?: ChatFile[]
}

function EnhancedMarkdownRenderer({
content,
isStreaming,
}: {
content: string
isStreaming?: boolean
}) {
return <MarkdownRenderer content={content} isStreaming={isStreaming} />
}

export const ClientChatMessage = memo(
function ClientChatMessage({ message }: { message: ChatMessage }) {
const [isCopied, setIsCopied] = useState(false)
Expand Down Expand Up @@ -192,7 +182,7 @@ export const ClientChatMessage = memo(
{JSON.stringify(cleanTextContent, null, 2)}
</pre>
) : (
<EnhancedMarkdownRenderer
<MarkdownRenderer
content={cleanTextContent as string}
isStreaming={message.isStreaming}
/>
Expand Down
Loading