diff --git a/desktop/src/components/chat/UserMessage.test.tsx b/desktop/src/components/chat/UserMessage.test.tsx new file mode 100644 index 00000000..efb519e9 --- /dev/null +++ b/desktop/src/components/chat/UserMessage.test.tsx @@ -0,0 +1,21 @@ +import { render, screen } from '@testing-library/react' +import { describe, expect, it } from 'vitest' +import { UserMessage } from './UserMessage' + +describe('UserMessage', () => { + it('keeps long URLs inside the message bubble', () => { + const longUrl = `https://cn.bing.com/search?q=${'encoded'.repeat(60)}` + + const { container } = render() + + const shell = container.querySelector('[data-message-shell="user"]') + const bubble = screen.getByText(longUrl) + + expect(shell?.className).toContain('min-w-0') + expect(bubble.className).toContain('min-w-0') + expect(bubble.className).toContain('max-w-full') + expect(bubble.className).toContain('whitespace-pre-wrap') + expect(bubble.style.overflowWrap).toBe('anywhere') + expect(bubble.style.wordBreak).toBe('break-word') + }) +}) diff --git a/desktop/src/components/chat/UserMessage.tsx b/desktop/src/components/chat/UserMessage.tsx index 9162384e..d66dadea 100644 --- a/desktop/src/components/chat/UserMessage.tsx +++ b/desktop/src/components/chat/UserMessage.tsx @@ -22,8 +22,12 @@ export function UserMessage({ content, attachments }: Props) { {hasText && (
{content}
diff --git a/desktop/src/components/markdown/MarkdownRenderer.tsx b/desktop/src/components/markdown/MarkdownRenderer.tsx index d9d0f236..f710de05 100644 --- a/desktop/src/components/markdown/MarkdownRenderer.tsx +++ b/desktop/src/components/markdown/MarkdownRenderer.tsx @@ -105,13 +105,13 @@ function parseMarkdown(content: string): { html: string; codeBlocks: CodeBlock[] return { html, codeBlocks } } -const BASE_PROSE_CLASSES = `markdown-prose prose prose-sm max-w-none text-[var(--color-text-primary)] +const BASE_PROSE_CLASSES = `markdown-prose prose prose-sm min-w-0 max-w-none break-words [overflow-wrap:anywhere] text-[var(--color-text-primary)] prose-headings:text-[var(--color-text-primary)] prose-headings:font-semibold prose-p:my-2 prose-p:leading-relaxed - prose-p:break-words + prose-p:break-words prose-p:[overflow-wrap:anywhere] prose-code:text-[13px] prose-code:text-[var(--color-code-fg)] prose-code:font-[var(--font-mono)] prose-code:bg-[var(--color-code-bg)] prose-code:border prose-code:border-[var(--color-border)] prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded-md prose-code:before:hidden prose-code:after:hidden prose-pre:!bg-transparent prose-pre:!p-0 prose-pre:!shadow-none - prose-a:text-[var(--color-text-accent)] prose-a:no-underline hover:prose-a:underline + prose-a:text-[var(--color-text-accent)] prose-a:no-underline prose-a:[overflow-wrap:anywhere] hover:prose-a:underline prose-strong:text-[var(--color-text-primary)] prose-ul:my-2 prose-ol:my-2 prose-li:my-0.5