Initial commit
This commit is contained in:
71
src/components/ds/Alert.jsx
Normal file
71
src/components/ds/Alert.jsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import * as React from 'react';
|
||||
import { AlertCircle, CheckCircle2, Info, TriangleAlert, X } from 'lucide-react';
|
||||
import { cva } from 'class-variance-authority';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const alertVariants = cva('flex items-start gap-3 rounded-xl border p-4 animate-slide-down', {
|
||||
variants: {
|
||||
tone: {
|
||||
info: 'bg-info-muted border-krow-blue/20 text-ink-2',
|
||||
success: 'bg-success-muted border-success/20 text-ink-2',
|
||||
warning: 'bg-warning-muted border-warning/25 text-ink-2',
|
||||
destructive: 'bg-destructive-muted border-destructive/20 text-ink-2',
|
||||
neutral: 'bg-surface-subtle border-border text-ink-2',
|
||||
},
|
||||
},
|
||||
defaultVariants: { tone: 'info' },
|
||||
});
|
||||
|
||||
const ICONS = {
|
||||
info: Info,
|
||||
success: CheckCircle2,
|
||||
warning: TriangleAlert,
|
||||
destructive: AlertCircle,
|
||||
neutral: Info,
|
||||
};
|
||||
|
||||
const ICON_COLORS = {
|
||||
info: 'text-krow-blue',
|
||||
success: 'text-success',
|
||||
warning: 'text-warning',
|
||||
destructive: 'text-destructive',
|
||||
neutral: 'text-ink-4',
|
||||
};
|
||||
|
||||
/**
|
||||
* Alert — an inline, persistent message about the state of the page.
|
||||
*
|
||||
* For transient confirmation of something the user just did, use `toast`
|
||||
* instead: an Alert that appears and disappears is easy to miss, and a toast
|
||||
* that persists is noise.
|
||||
*/
|
||||
export function Alert({ tone = 'info', title, children, icon, onDismiss, action, className, ...props }) {
|
||||
const Icon = icon || ICONS[tone];
|
||||
|
||||
return (
|
||||
<div role="alert" className={cn(alertVariants({ tone }), className)} {...props}>
|
||||
{Icon && <Icon className={cn('w-4.5 h-4.5 shrink-0 mt-0.5', ICON_COLORS[tone])} aria-hidden="true" />}
|
||||
|
||||
<div className="flex-1 min-w-0">
|
||||
{title && <p className="text-body-sm font-semibold text-ink-1">{title}</p>}
|
||||
{children && (
|
||||
<div className={cn('text-body-sm text-ink-2 leading-relaxed', title && 'mt-0.5')}>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
{action && <div className="mt-3">{action}</div>}
|
||||
</div>
|
||||
|
||||
{onDismiss && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onDismiss}
|
||||
aria-label="Dismiss"
|
||||
className="grid place-items-center w-6 h-6 rounded-md text-ink-4 hover:text-ink-1 hover:bg-black/5 transition-colors shrink-0 focus-ring-inset"
|
||||
>
|
||||
<X className="w-3.5 h-3.5" aria-hidden="true" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user