fix(ui-conversation): keep the summary suffix on one line
`flex: none` stops the `+n` box shrinking but not its text wrapping, so a row too narrow for title + separator + suffix broke the one-line summary in the exact case the slot exists for. Add `white-space: nowrap` and pin the declaration as CSS text, since jsdom has no layout. Also align the README's row illustration with the English rendering (the same sentence's plan-strip clause already used it), and record the two deferred review findings in the Agent Note so they survive merge.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* The one-line contract of the ToolRow summary line as CSS text. jsdom has no
|
||||
* layout, so the rendering specs (chat-tool-row.spec.tsx) can pin which spans
|
||||
* exist but not whether a narrow row still fits on one line; these read the
|
||||
* declarations the layout depends on.
|
||||
*/
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const css = readFileSync(fileURLToPath(new URL('../src/client/chat/ToolRow.module.css', import.meta.url)), 'utf8')
|
||||
/** Declarations only: the sheet's prose names the properties it explains. */
|
||||
const declarationText = css.replace(/\/\*[\s\S]*?\*\//g, ' ')
|
||||
|
||||
function declarations(selector: string): string[] {
|
||||
const rule = new RegExp(`\\${selector}\\s*\\{([^{}]*)\\}`).exec(declarationText)
|
||||
if (rule === null) throw new Error(`ToolRow.module.css has no \`${selector}\` rule`)
|
||||
return (rule[1] ?? '').split(';').map(part => part.trim()).filter(Boolean)
|
||||
}
|
||||
|
||||
describe('ToolRow.module.css summary line', () => {
|
||||
it('keeps the summary suffix on one line and unshrunk', () => {
|
||||
// `flex: none` stops the box shrinking, not the text wrapping: without
|
||||
// `nowrap`, a row too narrow for title + separator + suffix wraps the `+n`
|
||||
// onto a second line — the exact case the slot exists to survive.
|
||||
expect(declarations('.summarySuffix')).toEqual(expect.arrayContaining([
|
||||
'flex: none',
|
||||
'white-space: nowrap',
|
||||
]))
|
||||
})
|
||||
|
||||
it('leaves the truncation to the summary text alone', () => {
|
||||
// The suffix must never ellipsize: a clipped count reads as a smaller
|
||||
// number rather than as missing information.
|
||||
expect(declarations('.summary')).toEqual(expect.arrayContaining([
|
||||
'overflow: hidden',
|
||||
'text-overflow: ellipsis',
|
||||
'white-space: nowrap',
|
||||
]))
|
||||
expect(declarations('.summarySuffix')).not.toEqual(expect.arrayContaining(['text-overflow: ellipsis']))
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user