Files
gitmost/apps/client/src/features/ai-chat/components/chat-error-alert.tsx
claude_code 83c61641c9 fix(ai-chat): prevent error banner from clipping its text
The error banner is a flex child of the chat panel column. Mantine's
Alert root is `overflow: hidden`, which (per the CSS flexbox spec) drops
its automatic min-height to 0, so when the message history fills the
panel the flexbox compressed the banner below its content height and the
overflow:hidden clipped the detail text (e.g. "Please try again.").

Set flex-shrink: 0 on the banner so it always shows its full content; the
scrollable message list absorbs the height pressure instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 20:22:53 +03:00

50 lines
1.8 KiB
TypeScript

import { Alert, Group, Text, type AlertProps } from "@mantine/core";
import { IconAlertTriangle } from "@tabler/icons-react";
/**
* A classified AI chat error banner: a warning icon + bold heading on the first
* row, with the detail text spanning the full width below. Rendered for BOTH the
* live stream error (ChatThread) and a persisted assistant error (MessageItem),
* so this markup lives in one place. The detail is full-width (no hanging indent
* under the heading) so it wraps less and leaves no stranded icon / empty gap.
* The heading reuses Mantine's adaptive red "light" colour so it stays correct
* in dark mode. Layout-only props (mb/mt/...) are forwarded to the Alert root.
*/
interface ChatErrorAlertProps extends Omit<AlertProps, "title" | "children"> {
title: string;
detail: string;
}
export default function ChatErrorAlert({
title,
detail,
style,
...alertProps
}: ChatErrorAlertProps) {
// Mantine's own "light" alert colour, adaptive across light/dark schemes.
const accent = "var(--mantine-color-red-light-color)";
return (
// flexShrink: 0 keeps the banner fully visible. Mantine's Alert root is
// `overflow: hidden`, so as a flex child of the chat panel it can otherwise
// be compressed below its content height and clip the detail text; the
// scrollable message list absorbs the height pressure instead.
<Alert
{...alertProps}
variant="light"
color="red"
p="xs"
style={[{ flexShrink: 0 }, style]}
>
<Group gap={8} wrap="nowrap" align="center" mb={4}>
<IconAlertTriangle size={18} style={{ flex: "none", color: accent }} />
<Text fw={700} size="sm" lh={1.2} style={{ color: accent }}>
{title}
</Text>
</Group>
<Text size="sm" lh={1.4}>
{detail}
</Text>
</Alert>
);
}