fix: consistent font sizing in ToolCallWithResponse (#4167)

This commit is contained in:
Alex Hancock
2025-08-18 15:15:58 -04:00
committed by GitHub
parent 6522dc1cd5
commit 112ad20aeb
3 changed files with 37 additions and 25 deletions
+12 -11
View File
@@ -46,7 +46,7 @@ const CodeBlock = ({ language, children }: { language: string; children: string
<div className="relative group w-full"> <div className="relative group w-full">
<button <button
onClick={handleCopy} onClick={handleCopy}
className="absolute right-2 bottom-2 p-1.5 rounded-lg bg-gray-700/50 text-gray-300 className="absolute right-2 bottom-2 p-1.5 rounded-lg bg-gray-700/50 text-gray-300 font-sans text-sm
opacity-0 group-hover:opacity-100 transition-opacity duration-200 opacity-0 group-hover:opacity-100 transition-opacity duration-200
hover:bg-gray-600/50 hover:text-gray-100 z-10" hover:bg-gray-600/50 hover:text-gray-100 z-10"
title="Copy code" title="Copy code"
@@ -68,6 +68,7 @@ const CodeBlock = ({ language, children }: { language: string; children: string
whiteSpace: 'pre-wrap', whiteSpace: 'pre-wrap',
wordBreak: 'break-all', wordBreak: 'break-all',
overflowWrap: 'break-word', overflowWrap: 'break-word',
fontFamily: 'var(--font-sans)',
}, },
}} }}
> >
@@ -86,7 +87,7 @@ const MarkdownCode = React.forwardRef(function MarkdownCode(
return !inline && match ? ( return !inline && match ? (
<CodeBlock language={match[1]}>{String(children).replace(/\n$/, '')}</CodeBlock> <CodeBlock language={match[1]}>{String(children).replace(/\n$/, '')}</CodeBlock>
) : ( ) : (
<code ref={ref} {...props} className="break-all bg-inline-code whitespace-pre-wrap"> <code ref={ref} {...props} className="break-all bg-inline-code whitespace-pre-wrap font-sans">
{children} {children}
</code> </code>
); );
@@ -110,21 +111,21 @@ export default function MarkdownContent({ content, className = '' }: MarkdownCon
<div className="w-full overflow-x-hidden"> <div className="w-full overflow-x-hidden">
<ReactMarkdown <ReactMarkdown
remarkPlugins={[remarkGfm]} remarkPlugins={[remarkGfm]}
className={`prose prose-sm text-text-default dark:prose-invert w-full max-w-full word-break className={`prose prose-sm text-text-default dark:prose-invert w-full max-w-full word-break font-sans
prose-pre:p-0 prose-pre:m-0 !p-0 prose-pre:p-0 prose-pre:m-0 !p-0
prose-code:break-all prose-code:whitespace-pre-wrap prose-code:break-all prose-code:whitespace-pre-wrap prose-code:font-sans
prose-table:table prose-table:w-full prose-table:table prose-table:w-full
prose-blockquote:text-inherit prose-blockquote:text-inherit
prose-td:border prose-td:border-border-default prose-td:p-2 prose-td:border prose-td:border-border-default prose-td:p-2
prose-th:border prose-th:border-border-default prose-th:p-2 prose-th:border prose-th:border-border-default prose-th:p-2
prose-thead:bg-background-default prose-thead:bg-background-default
prose-h1:text-2xl prose-h1:font-normal prose-h1:mb-5 prose-h1:mt-0 prose-h1:text-2xl prose-h1:font-normal prose-h1:mb-5 prose-h1:mt-0 prose-h1:font-sans
prose-h2:text-xl prose-h2:font-normal prose-h2:mb-4 prose-h2:mt-4 prose-h2:text-xl prose-h2:font-normal prose-h2:mb-4 prose-h2:mt-4 prose-h2:font-sans
prose-h3:text-lg prose-h3:font-normal prose-h3:mb-3 prose-h3:mt-3 prose-h3:text-lg prose-h3:font-normal prose-h3:mb-3 prose-h3:mt-3 prose-h3:font-sans
prose-p:mt-0 prose-p:mb-2 prose-p:mt-0 prose-p:mb-2 prose-p:font-sans
prose-ol:my-2 prose-ol:my-2 prose-ol:font-sans
prose-ul:mt-0 prose-ul:mb-3 prose-ul:mt-0 prose-ul:mb-3 prose-ul:font-sans
prose-li:m-0 prose-li:m-0 prose-li:font-sans
${className}`} ${className}`}
components={{ components={{
a: ({ ...props }) => <a {...props} target="_blank" rel="noopener noreferrer" />, a: ({ ...props }) => <a {...props} target="_blank" rel="noopener noreferrer" />,
@@ -28,7 +28,7 @@ export function ToolCallArguments({ args }: ToolCallArgumentsProps) {
if (!needsExpansion) { if (!needsExpansion) {
return ( return (
<div className="text-xs mb-2"> <div className="font-sans text-sm mb-2">
<div className="flex flex-row"> <div className="flex flex-row">
<span className="text-textSubtle min-w-[140px]">{key}</span> <span className="text-textSubtle min-w-[140px]">{key}</span>
<span className="text-textPlaceholder">{value}</span> <span className="text-textPlaceholder">{value}</span>
@@ -38,7 +38,7 @@ export function ToolCallArguments({ args }: ToolCallArgumentsProps) {
} }
return ( return (
<div className="text-sm mb-2"> <div className="font-sans text-sm mb-2">
<div className="flex flex-row items-stretch"> <div className="flex flex-row items-stretch">
<button <button
onClick={() => toggleKey(key)} onClick={() => toggleKey(key)}
@@ -49,7 +49,10 @@ export function ToolCallArguments({ args }: ToolCallArgumentsProps) {
<div className="w-full flex items-stretch"> <div className="w-full flex items-stretch">
{isExpanded ? ( {isExpanded ? (
<div> <div>
<MarkdownContent content={value} className="text-sm text-textPlaceholder" /> <MarkdownContent
content={value}
className="font-sans text-sm text-textPlaceholder"
/>
</div> </div>
) : ( ) : (
<button onClick={() => toggleKey(key)} className="text-left text-textPlaceholder"> <button onClick={() => toggleKey(key)} className="text-left text-textPlaceholder">
@@ -78,7 +81,7 @@ export function ToolCallArguments({ args }: ToolCallArgumentsProps) {
return ( return (
<div className="mb-2"> <div className="mb-2">
<div className="flex flex-row text-xs"> <div className="flex flex-row font-sans text-sm">
<span className="text-textSubtle min-w-[140px]">{key}</span> <span className="text-textSubtle min-w-[140px]">{key}</span>
<pre className="whitespace-pre-wrap text-textPlaceholder overflow-x-auto max-w-full"> <pre className="whitespace-pre-wrap text-textPlaceholder overflow-x-auto max-w-full">
{content} {content}
@@ -34,7 +34,7 @@ export default function ToolCallWithResponse({
<> <>
<div <div
className={cn( className={cn(
'w-full text-sm rounded-lg overflow-hidden border-borderSubtle border bg-background-muted' 'w-full text-sm font-sans rounded-lg overflow-hidden border-borderSubtle border bg-background-muted'
)} )}
> >
<ToolCallView <ToolCallView
@@ -56,7 +56,7 @@ export default function ToolCallWithResponse({
<MCPUIResourceRenderer content={content} /> <MCPUIResourceRenderer content={content} />
<div className="mt-3 p-4 py-3 border border-borderSubtle rounded-lg bg-background-muted flex items-center"> <div className="mt-3 p-4 py-3 border border-borderSubtle rounded-lg bg-background-muted flex items-center">
<FlaskConical className="mr-2" size={20} /> <FlaskConical className="mr-2" size={20} />
<div className="text-sm font-medium mono"> <div className="text-sm font-sans">
MCP UI is experimental and may change at any time. MCP UI is experimental and may change at any time.
</div> </div>
</div> </div>
@@ -99,7 +99,7 @@ function ToolCallExpandable({
className="group w-full flex justify-between items-center pr-2 transition-colors rounded-none" className="group w-full flex justify-between items-center pr-2 transition-colors rounded-none"
variant="ghost" variant="ghost"
> >
<span className="flex items-center font-mono">{label}</span> <span className="flex items-center font-sans text-sm">{label}</span>
<ChevronRight <ChevronRight
className={cn( className={cn(
'group-hover:opacity-100 transition-transform opacity-70', 'group-hover:opacity-100 transition-transform opacity-70',
@@ -523,7 +523,7 @@ interface ToolDetailsViewProps {
function ToolDetailsView({ toolCall, isStartExpanded }: ToolDetailsViewProps) { function ToolDetailsView({ toolCall, isStartExpanded }: ToolDetailsViewProps) {
return ( return (
<ToolCallExpandable <ToolCallExpandable
label={<span className="pl-4 font-medium">Tool Details</span>} label={<span className="pl-4 font-sans text-sm">Tool Details</span>}
isStartExpanded={isStartExpanded} isStartExpanded={isStartExpanded}
> >
<div className="pr-4 pl-8"> <div className="pr-4 pl-8">
@@ -543,7 +543,7 @@ interface ToolResultViewProps {
function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) { function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) {
return ( return (
<ToolCallExpandable <ToolCallExpandable
label={<span className="pl-4 py-1 font-medium">Output</span>} label={<span className="pl-4 py-1 font-sans text-sm">Output</span>}
isStartExpanded={isStartExpanded} isStartExpanded={isStartExpanded}
> >
<div className="pl-4 pr-4 py-4"> <div className="pl-4 pr-4 py-4">
@@ -564,7 +564,9 @@ function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) {
}} }}
/> />
)} )}
{result.type === 'resource' && <pre>{JSON.stringify(result, null, 2)}</pre>} {result.type === 'resource' && (
<pre className="font-sans text-sm">{JSON.stringify(result, null, 2)}</pre>
)}
</div> </div>
</ToolCallExpandable> </ToolCallExpandable>
); );
@@ -586,12 +588,18 @@ function ToolLogsView({
if (boxRef.current) { if (boxRef.current) {
boxRef.current.scrollTop = boxRef.current.scrollHeight; boxRef.current.scrollTop = boxRef.current.scrollHeight;
} }
}, [logs]); }, [logs.length]);
// normally we do not want to put .length on an array in react deps:
//
// if the objects inside the array change but length doesn't change you want updates
//
// in this case, this is array of strings which once added do not change so this cuts
// down on the possibility of unwanted runs
return ( return (
<ToolCallExpandable <ToolCallExpandable
label={ label={
<span className="pl-4 py-1 font-medium flex items-center"> <span className="pl-4 py-1 font-sans text-sm flex items-center">
<span>Logs</span> <span>Logs</span>
{working && ( {working && (
<div className="mx-2 inline-block"> <div className="mx-2 inline-block">
@@ -612,7 +620,7 @@ function ToolLogsView({
className={`flex flex-col items-start space-y-2 overflow-y-auto p-4 ${working ? 'max-h-[4rem]' : 'max-h-[20rem]'}`} className={`flex flex-col items-start space-y-2 overflow-y-auto p-4 ${working ? 'max-h-[4rem]' : 'max-h-[20rem]'}`}
> >
{logs.map((log, i) => ( {logs.map((log, i) => (
<span key={i} className="font-mono text-sm text-textSubtle"> <span key={i} className="font-sans text-sm text-textSubtle">
{log} {log}
</span> </span>
))} ))}
@@ -627,7 +635,7 @@ const ProgressBar = ({ progress, total, message }: Omit<Progress, 'progressToken
return ( return (
<div className="w-full space-y-2"> <div className="w-full space-y-2">
{message && <div className="text-sm text-textSubtle">{message}</div>} {message && <div className="font-sans text-sm text-textSubtle">{message}</div>}
<div className="w-full bg-background-subtle rounded-full h-4 overflow-hidden relative"> <div className="w-full bg-background-subtle rounded-full h-4 overflow-hidden relative">
{isDeterminate ? ( {isDeterminate ? (