From e8e4df5ea9a828756c31e230ac50ca7c01bc78cf Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Wed, 27 May 2026 00:41:04 +0300 Subject: [PATCH] fix: smooth tool expansion animation --- .../chat/message/parts/ReasoningPart.tsx | 26 ++++++++++--------- .../chat/message/parts/ToolPart.tsx | 21 ++++++++------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx b/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx index e483685c..23f213ab 100644 --- a/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx +++ b/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx @@ -34,8 +34,8 @@ const cleanReasoningText = (text: string): string => { }; const SUMMARY_MAX_CHARS = 80; -const EXPANDED_CONTENT_UNMOUNT_DELAY_MS = 350; -const EXPANDED_CONTENT_SPRING = { type: 'spring' as const, visualDuration: 0.35, bounce: 0 }; +const EXPANDED_CONTENT_UNMOUNT_DELAY_MS = 200; +const EXPANDED_CONTENT_TRANSITION = { duration: 0.2, ease: 'easeOut' as const }; /** Strip common markdown syntax so the header preview reads as plain text. */ const stripMarkdown = (text: string): string => @@ -202,19 +202,17 @@ export const ReasoningTimelineBlock: React.FC = ({ contentMountedRef.current = true; if (!isExpanded) { element.style.height = '0px'; - element.style.opacity = '0'; element.style.overflow = 'hidden'; return; } element.style.height = '0px'; - element.style.opacity = '0'; element.style.overflow = 'hidden'; const animation = animate( element, - { height: 'auto', opacity: 1 }, - EXPANDED_CONTENT_SPRING, + { height: 'auto' }, + EXPANDED_CONTENT_TRANSITION, ); contentAnimationRef.current = animation; @@ -239,16 +237,14 @@ export const ReasoningTimelineBlock: React.FC = ({ if (isExpanded) { element.style.height = '0px'; - element.style.opacity = '0'; } else { element.style.height = `${element.scrollHeight}px`; - element.style.opacity = '1'; } const animation = animate( element, - { height: isExpanded ? 'auto' : '0px', opacity: isExpanded ? 1 : 0 }, - EXPANDED_CONTENT_SPRING, + { height: isExpanded ? 'auto' : '0px' }, + EXPANDED_CONTENT_TRANSITION, ); contentAnimationRef.current = animation; @@ -366,12 +362,18 @@ export const ReasoningTimelineBlock: React.FC = ({ aria-hidden={!isExpanded} style={{ height: isExpanded ? 'auto' : '0px', - opacity: isExpanded ? 1 : 0, overflow: isExpanded ? 'visible' : 'hidden', overflowAnchor: 'none', }} > -
+