Skip to content

Commit e316efa

Browse files
authored
fix(web): stop narrow chat error cards stacking titles vertically (#6295)
Move the long Open Design Cloud switch CTA into UserActionCard footer actions (same shell as run-recovery), add a card-width container query so head actions reflow when ChatPane is narrow, and soften title wrapping so CJK copy no longer renders one character per line.
1 parent 6801969 commit e316efa

4 files changed

Lines changed: 49 additions & 2 deletions

File tree

apps/web/src/components/AmrGuidance.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ export function AmrGuidance({
7575
tone="brand"
7676
title={t('chat.amrCard.switchTitle')}
7777
detailsLabel={t('brand.viewDetails')}
78-
actions={
78+
// Long localized CTA belongs in the footer row (same shell as run-
79+
// recovery). Head `actions` share a 3-column grid with the title; a
80+
// narrow ChatPane leaves the title a single CJK character wide and
81+
// `overflow-wrap: anywhere` turns "模型调用失败…" into a vertical stack.
82+
footerActions={
7983
<button
8084
type="button"
8185
className="amr-card__cta"

apps/web/src/components/UserActionCard.module.css

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
.card {
2+
/* ChatPane width is independent of the viewport — stack head actions off
3+
the card's own inline size via @container, not @media (max-width). */
4+
container-type: inline-size;
5+
container-name: user-action-card;
26
display: flex;
37
flex-direction: column;
48
gap: 8px;
@@ -52,7 +56,10 @@
5256
font-weight: 600;
5357
line-height: 1.4;
5458
color: var(--text-strong);
55-
overflow-wrap: anywhere;
59+
/* Prefer soft breaks over `anywhere` so a squeezed title does not stack
60+
every CJK character on its own line (vertical "模型调用失败…" flash). */
61+
overflow-wrap: break-word;
62+
word-break: normal;
5663
}
5764

5865
.actions {
@@ -62,6 +69,14 @@
6269
justify-content: flex-end;
6370
gap: 7px;
6471
min-width: 0;
72+
/* Cap so a long localized CTA cannot steal the entire title track. */
73+
max-width: min(100%, 16rem);
74+
}
75+
76+
.actions > * {
77+
min-width: 0;
78+
max-width: 100%;
79+
white-space: normal;
6580
}
6681

6782
.footer {
@@ -158,6 +173,20 @@
158173
}
159174
}
160175

176+
/* Prefer the card's own width: a desktop split with a ~320px ChatPane never
177+
matches viewport max-width:560px, so head CTAs must reflow via @container. */
178+
@container user-action-card (max-width: 420px) {
179+
.head {
180+
grid-template-columns: 24px minmax(0, 1fr);
181+
}
182+
183+
.actions {
184+
grid-column: 2 / -1;
185+
justify-content: flex-start;
186+
max-width: 100%;
187+
}
188+
}
189+
161190
@media (max-width: 560px) {
162191
.head {
163192
grid-template-columns: 24px minmax(0, 1fr);
@@ -166,6 +195,7 @@
166195
.actions {
167196
grid-column: 2;
168197
justify-content: flex-start;
198+
max-width: 100%;
169199
}
170200

171201
.footerActions {

apps/web/src/styles/chat.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,10 @@
12071207
font-size: 13px;
12081208
padding: 7px 14px;
12091209
border-radius: var(--radius-sm);
1210+
max-width: 100%;
1211+
white-space: normal;
1212+
text-align: left;
1213+
line-height: 1.35;
12101214
transition:
12111215
background 140ms cubic-bezier(0.23, 1, 0.32, 1),
12121216
border-color 140ms cubic-bezier(0.23, 1, 0.32, 1);

apps/web/tests/components/AmrGuidance.test.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,13 @@ describe('AmrGuidance', () => {
9696
});
9797
expect(onActivate).toHaveBeenCalledTimes(1);
9898
});
99+
100+
// Long CTA must live in the footer row so a narrow ChatPane does not
101+
// squeeze the Chinese title into a vertical one-character stack.
102+
it('places the switch CTA in the footer rather than the head actions column', () => {
103+
const { container } = renderGuidance();
104+
const cta = screen.getByRole('button', { name: 'Switch to Open Design Cloud & retry' });
105+
const footer = container.querySelector('[data-user-action-footer="true"]');
106+
expect(footer?.contains(cta)).toBe(true);
107+
});
99108
});

0 commit comments

Comments
 (0)