fix(activity): keep code blocks in row previews from rendering as scroll boxes (#25410)

The activity row previews the agent's last reply with the compact markdown
renderer, which draws fenced code blocks and tables as their own scrollable
boxes. Those boxes escaped the row's line clamp, so a reply with a code block
put a tall grey box with scrollbars in the middle of the list.

Row-scoped overrides now flatten code blocks and tables into plain wrapping
text, so the existing clamp cuts them like any other line. Other markdown
surfaces are unchanged.
This commit is contained in:
Jinwoo Hong
2026-10-05 01:53:53 -04:00
committed by GitHub
parent f873aaac5b
commit d279adc6ef
2 changed files with 35 additions and 1 deletions
@@ -262,4 +262,35 @@ describe('ActivityThreadHoverCard and ActivityThreadRow', () => {
expect(onJump).toHaveBeenCalledWith(thread)
})
it('flattens code blocks and tables in the reply preview so the line clamp cuts them', async () => {
const thread = createTestThread({
currentAgentState: null,
responsePreview:
'KK1-START\n\n```\n| metric | base median |\n| --- | --- |\n| p2 | 12 |\n```\n\n| a | b |\n| - | - |\n| 1 | 2 |'
})
await act(async () => {
root.render(<Harness thread={thread} />)
})
const pre = container.querySelector('pre')
const table = container.querySelector('table')
expect(pre).not.toBeNull()
expect(table).not.toBeNull()
const preview = pre?.closest<HTMLElement>('.line-clamp-3')
expect(preview).not.toBeNull()
expect(preview?.contains(table ?? null)).toBe(true)
// Why: the compact renderers draw both as scroll boxes; the row must undo that.
const previewClasses = preview?.className.split(/\s+/) ?? []
expect(previewClasses).toEqual(
expect.arrayContaining([
'[&_pre]:!max-h-none',
'[&_pre]:!overflow-visible',
'[&_pre]:!whitespace-normal',
'[&_div]:!overflow-visible',
'[&_:is(table,thead,tbody,tr,th,td)]:!inline'
])
)
})
})
@@ -133,7 +133,10 @@ export const ActivityThreadRow = React.memo(function ActivityThreadRow({
className={cn(
'min-w-0 break-words text-[13px] leading-5 text-foreground/80',
compactMode ? 'line-clamp-2' : 'line-clamp-3',
'[&_*]:!m-0 [&_*]:!p-0 [&_br]:hidden [&_ol]:list-none [&_ul]:list-none'
'[&_*]:!m-0 [&_*]:!p-0 [&_br]:hidden [&_ol]:list-none [&_ul]:list-none',
// Why: code blocks and tables otherwise render as scroll boxes the line clamp cannot cut.
'[&_pre]:!max-h-none [&_pre]:!overflow-visible [&_pre]:!whitespace-normal [&_pre]:!rounded-none [&_pre]:!bg-transparent [&_pre]:![font:inherit] [&_pre_code]:![font:inherit]',
'[&_div]:!overflow-visible [&_:is(table,thead,tbody,tr,th,td)]:!inline [&_:is(table,thead,tbody,tr,th,td)]:!align-baseline [&_:is(th,td)]:!border-0 [&_:is(th,td)]:!pr-2 [&_table]:![font:inherit]'
)}
/>
) : (