From 0068b53bb93fb0ea414eb9c3c1d4c2ec2402bf5f Mon Sep 17 00:00:00 2001 From: Sergey Kozyrenko Date: Fri, 31 Jul 2026 23:28:31 +0700 Subject: [PATCH] fix(flows): stop wide tables from horizontally scrolling the message list A markdown table with a long unbreakable cell (e.g. a FLAG hash) overflowed the message bubble and dragged the entire message list into a horizontal scroll, cutting off the left edge of every line. Wrap tables in an overflow-x-auto container so wide content scrolls inside its own box while the list scrolls only vertically. Covers both automation and assistant, which render through the same Markdown component. Co-Authored-By: Claude Opus 4.8 (cherry picked from commit 8745c51388948de1eeef405f9c1298693f5e53f4) --- .../src/components/shared/markdown.test.tsx | 27 +++++++++++++++++++ frontend/src/components/shared/markdown.tsx | 8 +++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/shared/markdown.test.tsx diff --git a/frontend/src/components/shared/markdown.test.tsx b/frontend/src/components/shared/markdown.test.tsx new file mode 100644 index 00000000..e48701a9 --- /dev/null +++ b/frontend/src/components/shared/markdown.test.tsx @@ -0,0 +1,27 @@ +import { render } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; + +import Markdown from './markdown'; + +const tableMarkdown = [ + '| Name | Email | Token |', + '| --- | --- | --- |', + '| sample | sample@example.com | TOKEN{0000000000000000000000000000000000000000000000000000000000000000} |', +].join('\n'); + +describe('Markdown', () => { + it('wraps a table in a horizontally scrollable container so wide content cannot widen the message list', () => { + const { container } = render({tableMarkdown}); + + const table = container.querySelector('table'); + expect(table).not.toBeNull(); + expect(table?.parentElement?.className).toContain('overflow-x-auto'); + }); + + it('keeps the table wrapped when search highlighting is active', () => { + const { container } = render({tableMarkdown}); + + const table = container.querySelector('table'); + expect(table?.parentElement?.className).toContain('overflow-x-auto'); + }); +}); diff --git a/frontend/src/components/shared/markdown.tsx b/frontend/src/components/shared/markdown.tsx index 83d5df40..ec793079 100644 --- a/frontend/src/components/shared/markdown.tsx +++ b/frontend/src/components/shared/markdown.tsx @@ -229,8 +229,14 @@ function Markdown({ children, className, searchValue }: MarkdownProps) { }; } + components.table = ({ children: nodeChildren, ...props }) => ( +
+ {processedSearch ? processTextNode(nodeChildren) : nodeChildren}
+
+ ); + return components; - }, [processedSearch, createComponentRenderer]); + }, [processedSearch, createComponentRenderer, processTextNode]); return (