learning_ai_common_plat/packages/ui/src/components/AlertBanner.tsx

56 lines
2.2 KiB
TypeScript

import * as React from 'react';
import { AlertCircle, CheckCircle2, Info, TriangleAlert } from 'lucide-react';
import { clsx } from 'clsx';
export type AlertBannerTone = 'info' | 'success' | 'warning' | 'error' | 'neutral';
export interface AlertBannerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
tone?: AlertBannerTone;
title?: React.ReactNode;
icon?: React.ReactNode;
}
const toneClass: Record<AlertBannerTone, string> = {
info: 'border-[var(--bl-info-border,var(--bl-border))] bg-[var(--bl-info-muted,var(--bl-surface-muted))] text-[var(--bl-info,var(--bl-accent))]',
success:
'border-[var(--bl-success-border,var(--bl-border))] bg-[var(--bl-success-muted,var(--bl-surface-muted))] text-[var(--bl-success)]',
warning:
'border-[var(--bl-warning-border,var(--bl-border))] bg-[var(--bl-warning-muted,var(--bl-surface-muted))] text-[var(--bl-warning)]',
error:
'border-[var(--bl-danger-border,var(--bl-border))] bg-[var(--bl-danger-muted,var(--bl-surface-muted))] text-[var(--bl-danger)]',
neutral: 'border-[var(--bl-border)] bg-[var(--bl-surface-muted)] text-[var(--bl-text-secondary)]',
};
const iconByTone: Record<AlertBannerTone, React.ReactNode> = {
info: <Info className="h-4 w-4" aria-hidden="true" />,
success: <CheckCircle2 className="h-4 w-4" aria-hidden="true" />,
warning: <TriangleAlert className="h-4 w-4" aria-hidden="true" />,
error: <AlertCircle className="h-4 w-4" aria-hidden="true" />,
neutral: <Info className="h-4 w-4" aria-hidden="true" />,
};
export function AlertBanner({
tone = 'info',
title,
icon,
className,
children,
...props
}: AlertBannerProps) {
return (
<div
className={clsx('flex gap-3 rounded-xl border px-4 py-3 text-sm', toneClass[tone], className)}
role={tone === 'error' || tone === 'warning' ? 'alert' : 'status'}
{...props}
>
<div className="mt-0.5 shrink-0">{icon ?? iconByTone[tone]}</div>
<div className="min-w-0">
{title && (
<div className="font-semibold leading-5 text-[var(--bl-text-primary)]">{title}</div>
)}
<div className="leading-6 text-[var(--bl-text-secondary)]">{children}</div>
</div>
</div>
);
}