mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(composer): lone typing group uses the full row width instead of truncating at the strip cap
- BotActivityBar.tsx: apply the typing slot's max-w-64 cap only when the
group shares the strip with working-agent pills. The cap exists so a
long "X, Y, and N more are typing" label can't inflate the strip's
scroll extent alongside pills, but it was unconditional — as the
strip's LONE item a two-name label ("Alpha Debug and Beta Debug are
typing...") got cut off at 256px even with the row mostly empty. The
lone item already shrinks with the container (min-w-0 through the
slot chain), so it now consumes the row's free width and only
ellipsizes when the container is genuinely narrow.
- channels.spec.ts: add "lone typing group uses the full row width"
e2e regression — three typers push the label past the old cap, then
asserts no truncation at full width (scrollWidth <= clientWidth) and
graceful ellipsizing without scroll fades at a 200px row. Verified
the test fails against the old unconditional cap.
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
@@ -775,10 +775,16 @@ export function BotActivityComposerAction({
|
||||
{() => (
|
||||
<div
|
||||
className={cn(
|
||||
// Cap like the pills (which use max-w-50 each) so a
|
||||
// long "X, Y, and N more are typing" label truncates
|
||||
// instead of inflating the scroll extent.
|
||||
"flex h-7 min-w-0 max-w-64 items-center",
|
||||
"flex h-7 min-w-0 items-center",
|
||||
// Only when sharing the strip with pills does the
|
||||
// group need a width cap (like the pills' max-w-50
|
||||
// each) so a long "X, Y, and N more are typing" label
|
||||
// truncates instead of inflating the scroll extent.
|
||||
// As the strip's lone item it shrinks with the
|
||||
// container instead (min-w-0 through the slot chain),
|
||||
// so a cap would only cut the label off in a row that
|
||||
// has room to spare.
|
||||
orderedAgents.length > 0 && "max-w-64",
|
||||
// Composer-edge alignment when the typing group leads
|
||||
// the strip (no pills): 0.75rem/1rem composer padding
|
||||
// + 1px border. Mirrors the standalone row's old
|
||||
|
||||
@@ -3109,6 +3109,52 @@ test("typing indicator shows avatars and maintains stable name order", async ({
|
||||
).toContainText("alice and bob are typing");
|
||||
});
|
||||
|
||||
test("lone typing group uses the full row width instead of truncating at the strip cap", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/");
|
||||
|
||||
await page.getByTestId("channel-random").click();
|
||||
await expect(page.getByTestId("chat-title")).toHaveText("random");
|
||||
await waitForMockLiveSubscription(page, "random", KIND_TYPING_INDICATOR);
|
||||
|
||||
// Three typers push the label past the strip's shared-slot cap (max-w-64,
|
||||
// 256px): with no pills the typing group is the strip's LONE item and must
|
||||
// consume the row's free width instead of cutting the label off mid-name.
|
||||
for (const identity of [
|
||||
TEST_IDENTITIES.alice,
|
||||
TEST_IDENTITIES.bob,
|
||||
TEST_IDENTITIES.charlie,
|
||||
]) {
|
||||
await page.evaluate((pubkey) => {
|
||||
window.__BUZZ_E2E_EMIT_MOCK_TYPING__?.({
|
||||
channelName: "random",
|
||||
pubkey,
|
||||
});
|
||||
}, identity.pubkey);
|
||||
}
|
||||
|
||||
const label = page.getByTestId("message-typing-indicator-label");
|
||||
await expect(label).toContainText("alice, bob, and charlie are typing");
|
||||
|
||||
// No truncation with room to spare: the label's content fits its box.
|
||||
await expect
|
||||
.poll(() => label.evaluate((el) => el.scrollWidth - el.clientWidth))
|
||||
.toBeLessThanOrEqual(0);
|
||||
|
||||
// Genuinely narrow, the lone group still shrinks with the container and
|
||||
// ellipsizes (rather than overflowing into scroll under an edge fade).
|
||||
await page
|
||||
.getByTestId("channel-composer-activity-row")
|
||||
.evaluate((element) => {
|
||||
element.style.width = "200px";
|
||||
});
|
||||
await expect
|
||||
.poll(() => label.evaluate((el) => el.scrollWidth - el.clientWidth))
|
||||
.toBeGreaterThan(0);
|
||||
await expect(page.getByTestId("bot-activity-strip-fade-end")).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("sidebar shows unread indicator for newly active channels", async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
Reference in New Issue
Block a user