refactor(chat): use ds-* Tailwind utilities in message components

Replace bg-[var(--ds-*)], text-[color:var(--ds-*)], and border arbitrary
values with bg-ds-*, text-ds-*, and border-ds-* across cards and markdown.

Made-with: Cursor
This commit is contained in:
Douglas 2026-04-23 11:18:57 +01:00
parent 8106c9a15e
commit 31bcf19bda
7 changed files with 33 additions and 33 deletions

View file

@ -113,14 +113,14 @@ export function AgentMessageCard({
ipcRenderer?.invoke('reveal-in-folder', file.filePath);
}}
key={'attache-' + file.fileName}
className="gap-2 rounded-2xl py-1 pl-2 flex w-full cursor-pointer items-center border border-solid border-[color:var(--ds-border-neutral-subtle-default)] bg-[var(--ds-bg-neutral-default-default)]"
className="gap-2 rounded-2xl py-1 pl-2 flex w-full cursor-pointer items-center border border-solid border-ds-border-neutral-subtle-default bg-ds-bg-neutral-default-default"
>
<FileText size={24} className="flex-shrink-0" />
<div className="flex flex-col">
<div className="text-body max-w-48 text-sm font-bold overflow-hidden text-ellipsis whitespace-nowrap text-[color:var(--ds-text-neutral-default-default)]">
<div className="text-body max-w-48 text-sm font-bold overflow-hidden text-ellipsis whitespace-nowrap text-ds-text-neutral-default-default">
{file?.fileName?.split('.')[0]}
</div>
<div className="text-xs font-medium leading-29 text-[color:var(--ds-text-neutral-default-default)]">
<div className="text-xs font-medium leading-29 text-ds-text-neutral-default-default">
{file?.fileName?.split('.')[1]}
</div>
</div>
@ -142,7 +142,7 @@ export function AgentMessageCard({
aria-label={t('setting.copy')}
>
{copied ? (
<Check className="h-4 w-4 text-[color:var(--ds-text-success-default-default)]" />
<Check className="h-4 w-4 text-ds-text-success-default-default" />
) : (
<Copy className="h-4 w-4" />
)}

View file

@ -83,7 +83,7 @@ export function FeedbackCard({
buttonContent="icon-only"
>
{copied ? (
<Check className="h-4 w-4 text-[color:var(--ds-text-success-default-default)]" />
<Check className="h-4 w-4 text-ds-text-success-default-default" />
) : (
<Copy className="h-4 w-4" />
)}
@ -91,12 +91,12 @@ export function FeedbackCard({
</div>
{/* Title */}
<p className="font-inter text-sm font-bold leading-normal w-full text-[color:var(--ds-text-neutral-default-default)]">
<p className="font-inter text-sm font-bold leading-normal w-full text-ds-text-neutral-default-default">
{title}
</p>
{/* Content */}
<p className="font-inter text-sm font-medium leading-normal w-full text-[color:var(--ds-text-neutral-default-default)]">
<p className="font-inter text-sm font-medium leading-normal w-full text-ds-text-neutral-default-default">
{content}
</p>

View file

@ -143,7 +143,7 @@ export const MarkDown = memo(
.join('\n')
.trim();
setHtml(
`<pre class="bg-[var(--ds-bg-neutral-strong-default)] p-2 rounded text-xs font-mono overflow-x-auto whitespace-pre-wrap break-all" style="word-break: break-all;"><code>${escapeHtml(formattedHtml)}</code></pre>`
`<pre class="bg-ds-bg-neutral-strong-default p-2 rounded text-xs font-mono overflow-x-auto whitespace-pre-wrap break-all" style="word-break: break-all;"><code>${escapeHtml(formattedHtml)}</code></pre>`
);
if (displayedContent === content && renderCompleteRef.current) {
renderCompleteRef.current();
@ -187,7 +187,7 @@ export const MarkDown = memo(
// Fallback: show alt text or placeholder
const altMatch = fullTag.match(/alt=["']([^"']*)["']/);
const alt = altMatch ? altMatch[1] : 'image';
const placeholder = `<span class="inline-block text-sm text-[color:var(--ds-text-neutral-muted-default)]">[${alt}]</span>`;
const placeholder = `<span class="inline-block text-sm text-ds-text-neutral-muted-default">[${alt}]</span>`;
rawHtml = rawHtml.replace(fullTag, placeholder);
}
} catch (error) {

View file

@ -92,7 +92,7 @@ export function NoticeCard() {
key={`taskList-${index}`}
className={`gap-2 rounded-lg ease-in-out animate-in fade-in-0 slide-in-from-left-2 flex cursor-pointer border border-solid border-transparent transition-all duration-300`}
>
<div className="m-1.5 mt-2 h-1 w-1 rounded-full bg-[var(--ds-icon-neutral-default-default)]"></div>
<div className="m-1.5 mt-2 h-1 w-1 rounded-full bg-ds-icon-neutral-default-default"></div>
<div className="text-sm font-normal leading-normal flex flex-1 flex-col items-start justify-center">
{cot}
</div>

View file

@ -67,7 +67,7 @@ export const SummaryMarkDown = ({
.trim();
return (
<div className="prose prose-sm max-w-none">
<pre className="mb-3 rounded-lg p-3 font-mono text-xs overflow-x-auto border border-[color:var(--ds-border-status-completed-default-default)] bg-[var(--ds-bg-status-completed-subtle-default)] whitespace-pre-wrap text-[color:var(--ds-text-neutral-default-default)]">
<pre className="mb-3 rounded-lg p-3 font-mono text-xs overflow-x-auto border border-ds-border-status-completed-default-default bg-ds-bg-completed-subtle-default whitespace-pre-wrap text-ds-text-neutral-default-default">
<code>{formattedHtml}</code>
</pre>
</div>
@ -79,67 +79,67 @@ export const SummaryMarkDown = ({
<ReactMarkdown
components={{
h1: ({ children }) => (
<h1 className="mb-3 gap-2 pb-2 text-xl font-bold flex items-center border-b border-[color:var(--ds-border-status-completed-default-default)] text-[color:var(--ds-text-success-default-default)]">
<h1 className="mb-3 gap-2 pb-2 text-xl font-bold flex items-center border-b border-ds-border-status-completed-default-default text-ds-text-success-default-default">
{children}
</h1>
),
h2: ({ children }) => (
<h2 className="mb-3 mt-4 gap-2 text-lg font-semibold flex items-center text-[color:var(--ds-text-status-completed-muted-default)]">
<h2 className="mb-3 mt-4 gap-2 text-lg font-semibold flex items-center text-ds-text-status-completed-muted-default">
{children}
</h2>
),
h3: ({ children }) => (
<h3 className="mb-2 mt-3 text-base font-medium text-[color:var(--ds-text-status-completed-muted-default)]">
<h3 className="mb-2 mt-3 text-base font-medium text-ds-text-status-completed-muted-default">
{children}
</h3>
),
p: ({ children }) => (
<p className="m-0 mb-3 text-sm font-normal leading-relaxed whitespace-pre-wrap text-[color:var(--ds-text-neutral-default-default)]">
<p className="m-0 mb-3 text-sm font-normal leading-relaxed whitespace-pre-wrap text-ds-text-neutral-default-default">
{children}
</p>
),
ul: ({ children }) => (
<ul className="mb-3 ml-2 space-y-1 text-sm list-inside list-disc text-[color:var(--ds-text-neutral-default-default)]">
<ul className="mb-3 ml-2 space-y-1 text-sm list-inside list-disc text-ds-text-neutral-default-default">
{children}
</ul>
),
ol: ({ children }) => (
<ol className="mb-3 ml-2 space-y-1 text-sm list-inside list-decimal text-[color:var(--ds-text-neutral-default-default)]">
<ol className="mb-3 ml-2 space-y-1 text-sm list-inside list-decimal text-ds-text-neutral-default-default">
{children}
</ol>
),
li: ({ children }) => (
<li className="mb-1 leading-relaxed text-[color:var(--ds-text-neutral-default-default)]">
<li className="mb-1 leading-relaxed text-ds-text-neutral-default-default">
{children}
</li>
),
code: ({ children }) => (
<code className="rounded px-2 py-1 font-mono text-xs bg-[var(--ds-bg-status-completed-subtle-default)] text-[color:var(--ds-text-success-default-default)]">
<code className="rounded px-2 py-1 font-mono text-xs bg-ds-bg-completed-subtle-default text-ds-text-success-default-default">
{children}
</code>
),
pre: ({ children }) => (
<pre className="mb-3 rounded-lg p-3 font-mono text-xs overflow-x-auto border border-[color:var(--ds-border-status-completed-default-default)] bg-[var(--ds-bg-status-completed-subtle-default)] whitespace-pre-wrap text-[color:var(--ds-text-neutral-default-default)]">
<pre className="mb-3 rounded-lg p-3 font-mono text-xs overflow-x-auto border border-ds-border-status-completed-default-default bg-ds-bg-completed-subtle-default whitespace-pre-wrap text-ds-text-neutral-default-default">
{children}
</pre>
),
blockquote: ({ children }) => (
<blockquote className="mb-3 rounded-r-lg py-2 pl-4 border-l-4 border-[color:var(--ds-border-status-completed-default-default)] bg-[var(--ds-bg-status-completed-subtle-default)] text-[color:var(--ds-text-status-completed-muted-default)] italic">
<blockquote className="mb-3 rounded-r-lg py-2 pl-4 border-l-4 border-ds-border-status-completed-default-default bg-ds-bg-completed-subtle-default text-ds-text-status-completed-muted-default italic">
{children}
</blockquote>
),
strong: ({ children }) => (
<strong className="font-semibold text-[color:var(--ds-text-success-default-default)]">
<strong className="font-semibold text-ds-text-success-default-default">
{children}
</strong>
),
em: ({ children }) => (
<em className="text-[color:var(--ds-text-status-completed-muted-default)] italic">
<em className="text-ds-text-status-completed-muted-default italic">
{children}
</em>
),
hr: () => (
<hr className="my-4 border-[color:var(--ds-border-status-completed-default-default)]" />
<hr className="my-4 border-ds-border-status-completed-default-default" />
),
}}
>

View file

@ -174,7 +174,7 @@ export function UserMessageCard({
{/* File Name */}
<p
className={cn(
"my-0 text-xs font-bold leading-tight relative min-h-px min-w-px flex-1 overflow-hidden font-['Inter'] overflow-ellipsis whitespace-nowrap text-[color:var(--ds-text-neutral-default-default)]"
"my-0 text-xs font-bold leading-tight relative min-h-px min-w-px flex-1 overflow-hidden font-['Inter'] overflow-ellipsis whitespace-nowrap text-ds-text-neutral-default-default"
)}
title={file.fileName}
>
@ -195,14 +195,14 @@ export function UserMessageCard({
size="xs"
buttonContent="text"
variant="ghost"
className="rounded-lg relative flex items-center bg-[var(--ds-bg-neutral-strong-default)]"
className="rounded-lg relative flex items-center bg-ds-bg-neutral-strong-default"
onMouseEnter={openRemainingPopover}
onMouseLeave={scheduleCloseRemainingPopover}
onClick={(e) => {
e.stopPropagation();
}}
>
<span className="text-label-xs font-bold leading-tight font-['Inter'] whitespace-nowrap text-[color:var(--ds-text-neutral-default-default)]">
<span className="text-label-xs font-bold leading-tight font-['Inter'] whitespace-nowrap text-ds-text-neutral-default-default">
{remainingCount}+
</span>
</Button>
@ -210,7 +210,7 @@ export function UserMessageCard({
<PopoverContent
align="end"
sideOffset={4}
className="max-w-40 rounded-md p-1 shadow-perfect !w-auto border border-[color:var(--ds-border-neutral-subtle-default)] bg-[var(--ds-bg-neutral-default-default)]"
className="max-w-40 rounded-md p-1 shadow-perfect !w-auto border border-ds-border-neutral-subtle-default bg-ds-bg-neutral-default-default"
onMouseEnter={openRemainingPopover}
onMouseLeave={scheduleCloseRemainingPopover}
>
@ -219,7 +219,7 @@ export function UserMessageCard({
return (
<div
key={file.filePath}
className="gap-1 rounded-lg py-0.5 flex cursor-pointer items-center bg-[var(--ds-bg-neutral-strong-default)] transition-colors duration-300 hover:bg-[var(--ds-bg-neutral-default-hover)]"
className="gap-1 rounded-lg py-0.5 flex cursor-pointer items-center bg-ds-bg-neutral-strong-default transition-colors duration-300 hover:bg-ds-bg-neutral-default-hover"
onMouseLeave={() =>
setHoveredFilePath((prev) =>
prev === file.filePath ? null : prev
@ -237,7 +237,7 @@ export function UserMessageCard({
<div className="h-6 w-6 rounded-md flex items-center justify-center">
{getFileIcon(file.fileName)}
</div>
<p className="my-0 text-xs font-bold leading-tight flex-1 overflow-hidden font-['Inter'] text-ellipsis whitespace-nowrap text-[color:var(--ds-text-neutral-default-default)]">
<p className="my-0 text-xs font-bold leading-tight flex-1 overflow-hidden font-['Inter'] text-ellipsis whitespace-nowrap text-ds-text-neutral-default-default">
{file.fileName}
</p>
</div>
@ -308,7 +308,7 @@ export function UserMessageCard({
buttonContent="icon-only"
>
{copied ? (
<Check className="h-4 w-4 text-[color:var(--ds-text-success-default-default)]" />
<Check className="h-4 w-4 text-ds-text-success-default-default" />
) : (
<Copy />
)}

View file

@ -122,8 +122,8 @@ export function UserMessageRichContent({
const bodyClass =
variant === 'card'
? 'text-[color:var(--ds-text-neutral-default-default)] font-sans relative z-0 break-words whitespace-pre-wrap'
: 'text-[color:var(--ds-text-neutral-muted-default)] font-sans relative z-0 min-w-0 break-words font-normal line-clamp-1';
? 'text-ds-text-neutral-default-default font-sans relative z-0 break-words whitespace-pre-wrap'
: 'text-ds-text-neutral-muted-default font-sans relative z-0 min-w-0 break-words font-normal line-clamp-1';
return (
<div className={cn('min-w-0', className)}>