fix: improve light theme readability for tool badges and user bubbles
- Expose resolvedTheme in ThemeContext for theme-aware rendering - Tool call badges: darker text colors and higher bg opacity in light theme - User message bubbles: increased bg opacity and border strength in light theme - Progress bars and send button already use accent CSS variables (no change needed) Closes feedback #60
This commit is contained in:
19
FEEDBACK.md
19
FEEDBACK.md
@@ -649,10 +649,17 @@
|
||||
## Item #60
|
||||
- **Date:** 2026-02-13
|
||||
- **Priority:** high
|
||||
- **Status:** pending
|
||||
- **Status:** done
|
||||
- **Completed:** 2026-02-13 — commit `e596eea`
|
||||
- **Description:** Light theme fixes — 4 issues:
|
||||
1. Progress bar colors (sidebar + header) should follow accent color, not hardcoded cyan
|
||||
2. Send button gradient should adapt to theme/accent
|
||||
3. Tool call badges are unreadable in light theme (dark-only Tailwind classes like amber-950, sky-950)
|
||||
4. User message bubble background too subtle in light theme — needs more contrast
|
||||
- Sub-agent working on this (session pinchchat-light-theme-fix)
|
||||
1. Progress bar colors (sidebar + header) should follow accent color, not hardcoded cyan — ✅ already using `--pc-accent-rgb`
|
||||
2. Send button gradient should adapt to theme/accent — ✅ already using `var(--pc-accent)`
|
||||
3. Tool call badges are unreadable in light theme (dark-only Tailwind classes like amber-950, sky-950) — ✅ fixed: darker text + higher bg opacity in light mode
|
||||
4. User message bubble background too subtle in light theme — needs more contrast — ✅ fixed: higher opacity bg + border in light mode
|
||||
- Added `resolvedTheme` to ThemeContext for components to adapt to current theme
|
||||
|
||||
## Item #61
|
||||
- **Date:** 2026-02-13
|
||||
- **Priority:** medium
|
||||
- **Status:** pending
|
||||
- **Description:** Markdown unordered lists (- item, * item) are not rendered properly in chat messages. They appear as raw text instead of formatted bullet points. Need to verify remarkGfm/ReactMarkdown config handles list rendering correctly, and ensure CSS styles are applied for ul/ol elements in the markdown-body class.
|
||||
|
||||
@@ -7,6 +7,7 @@ import remarkBreaks from 'remark-breaks';
|
||||
import rehypeHighlight from 'rehype-highlight';
|
||||
import { rehypeHighlightOptions } from '../lib/highlight';
|
||||
import type { ChatMessage as ChatMessageType, MessageBlock } from '../types';
|
||||
import { useTheme } from '../hooks/useTheme';
|
||||
import { ThinkingBlock } from './ThinkingBlock';
|
||||
import { ThinkingIndicator } from './ThinkingIndicator';
|
||||
import { CodeBlock } from './CodeBlock';
|
||||
@@ -382,6 +383,8 @@ function SystemEventMessage({ message }: { message: ChatMessageType }) {
|
||||
|
||||
export function ChatMessageComponent({ message: rawMessage, onRetry, agentAvatarUrl }: { message: ChatMessageType; onRetry?: (text: string) => void; agentAvatarUrl?: string }) {
|
||||
useLocale(); // re-render on locale change
|
||||
const { resolvedTheme } = useTheme();
|
||||
const isLight = resolvedTheme === 'light';
|
||||
const [showRawJson, setShowRawJson] = useState(false);
|
||||
|
||||
// Strip webhook/hook scaffolding from user messages before rendering
|
||||
@@ -446,7 +449,9 @@ export function ChatMessageComponent({ message: rawMessage, onRetry, agentAvatar
|
||||
<div className={`min-w-0 max-w-[80%] ${isUser ? 'text-right' : ''}`}>
|
||||
<div className={`group relative inline-block text-left rounded-3xl px-4 py-3 text-sm leading-relaxed max-w-full overflow-hidden ${
|
||||
isUser
|
||||
? 'bg-[rgba(var(--pc-accent-rgb),0.08)] text-pc-text border border-[rgba(var(--pc-accent-rgb),0.2)]'
|
||||
? (isLight
|
||||
? 'bg-[rgba(var(--pc-accent-rgb),0.12)] text-pc-text border border-[rgba(var(--pc-accent-rgb),0.3)]'
|
||||
: 'bg-[rgba(var(--pc-accent-rgb),0.08)] text-pc-text border border-[rgba(var(--pc-accent-rgb),0.2)]')
|
||||
: 'bg-pc-elevated/40 text-pc-text border border-pc-border shadow-[0_0_0_1px_rgba(255,255,255,0.03)]'
|
||||
}`}>
|
||||
{/* Action buttons */}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
|
||||
import { ChevronRight, ChevronDown, Check, Copy, WrapText, AlignLeft } from 'lucide-react';
|
||||
import hljs from '../lib/highlight';
|
||||
import { useT } from '../hooks/useLocale';
|
||||
import { useTheme } from '../hooks/useTheme';
|
||||
import { ImageBlock } from './ImageBlock';
|
||||
import { useToolCollapse } from '../hooks/useToolCollapse';
|
||||
|
||||
@@ -31,13 +32,19 @@ const defaultRGB: ToolRGB = { r: 161, g: 161, b: 170 }; // zinc
|
||||
|
||||
function rgbStr(c: ToolRGB): string { return `${c.r},${c.g},${c.b}`; }
|
||||
|
||||
function getColorStyles(name: string): { badge: React.CSSProperties; text: React.CSSProperties; expand: React.CSSProperties; glow: string } {
|
||||
function getColorStyles(name: string, isLight = false): { badge: React.CSSProperties; text: React.CSSProperties; expand: React.CSSProperties; glow: string } {
|
||||
const c = toolRGBs[name] || defaultRGB;
|
||||
const rgb = rgbStr(c);
|
||||
// Use darker text and higher bg opacity in light theme for readability
|
||||
const badgeBgAlpha = isLight ? 0.15 : 0.10;
|
||||
const expandBgAlpha = isLight ? 0.08 : 0.05;
|
||||
const textColor = isLight
|
||||
? `rgb(${Math.round(c.r * 0.6)},${Math.round(c.g * 0.6)},${Math.round(c.b * 0.6)})`
|
||||
: `rgb(${c.r},${c.g},${c.b})`;
|
||||
return {
|
||||
badge: { borderColor: `rgba(${rgb},0.3)`, backgroundColor: `rgba(${rgb},0.10)` },
|
||||
text: { color: `rgb(${c.r},${c.g},${c.b})` },
|
||||
expand: { borderColor: `rgba(${rgb},0.2)`, backgroundColor: `rgba(${rgb},0.05)` },
|
||||
badge: { borderColor: `rgba(${rgb},0.3)`, backgroundColor: `rgba(${rgb},${badgeBgAlpha})` },
|
||||
text: { color: textColor },
|
||||
expand: { borderColor: `rgba(${rgb},0.2)`, backgroundColor: `rgba(${rgb},${expandBgAlpha})` },
|
||||
glow: `shadow-[0_0_8px_rgba(${rgb},0.15)]`,
|
||||
};
|
||||
}
|
||||
@@ -253,8 +260,9 @@ export function ToolCall({ name, input, result }: { name: string; input?: Record
|
||||
const [open, setOpen] = useState(false);
|
||||
const [wrap, setWrap] = useState(true);
|
||||
const { globalState, version } = useToolCollapse();
|
||||
const { resolvedTheme } = useTheme();
|
||||
const lastVersion = useRef(version);
|
||||
const cs = getColorStyles(name);
|
||||
const cs = getColorStyles(name, resolvedTheme === 'light');
|
||||
|
||||
// Respond to global collapse/expand commands
|
||||
useEffect(() => {
|
||||
|
||||
@@ -180,8 +180,10 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
|
||||
return () => mq.removeEventListener('change', handler);
|
||||
}, [theme]);
|
||||
|
||||
const resolvedTheme = resolveTheme(theme);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, accent, setTheme, setAccent }}>
|
||||
<ThemeContext.Provider value={{ theme, accent, resolvedTheme, setTheme, setAccent }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,8 @@ export type AccentColor = 'cyan' | 'violet' | 'emerald' | 'amber' | 'rose' | 'bl
|
||||
export interface ThemeContextValue {
|
||||
theme: ThemeName;
|
||||
accent: AccentColor;
|
||||
/** Resolved concrete theme (never 'system'). */
|
||||
resolvedTheme: 'dark' | 'light' | 'oled';
|
||||
setTheme: (t: ThemeName) => void;
|
||||
setAccent: (a: AccentColor) => void;
|
||||
}
|
||||
@@ -13,6 +15,7 @@ export interface ThemeContextValue {
|
||||
export const ThemeContext = createContext<ThemeContextValue>({
|
||||
theme: 'dark',
|
||||
accent: 'cyan',
|
||||
resolvedTheme: 'dark',
|
||||
setTheme: () => {},
|
||||
setAccent: () => {},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user