91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
'use client';
|
|
|
|
/**
|
|
* TipBox Component - Dual Style System
|
|
*
|
|
* Provides two distinct styles for callouts/notes:
|
|
*
|
|
* 1. Compact Style (Variant A inspired):
|
|
* - Small emoji icon on left
|
|
* - Compact padding (p-4)
|
|
* - Smaller text (text-sm)
|
|
* - Subtle background with thin border
|
|
* - Best for minor notes and tips
|
|
*
|
|
* 2. Prominent Style (Adapted from Variant C):
|
|
* - NO icon
|
|
* - Larger padding (p-6)
|
|
* - Larger text (text-base)
|
|
* - Gradient border with soft glow
|
|
* - More visual weight
|
|
* - Best for important warnings and security notices
|
|
*
|
|
* Usage:
|
|
* <TipBox variant="compact" type="info">
|
|
* This is a compact tip
|
|
* </TipBox>
|
|
*
|
|
* <TipBox variant="prominent" type="warning">
|
|
* This is an important security warning
|
|
* </TipBox>
|
|
*/
|
|
|
|
import { ReactNode } from 'react';
|
|
|
|
type TipType = 'info' | 'warning' | 'success';
|
|
type TipVariant = 'compact' | 'prominent';
|
|
|
|
interface TipBoxProps {
|
|
children: ReactNode;
|
|
variant?: TipVariant;
|
|
type?: TipType;
|
|
}
|
|
|
|
const icons: Record<TipType, string> = {
|
|
info: '💡',
|
|
warning: '⚠️',
|
|
success: '✓',
|
|
};
|
|
|
|
const compactStyles: Record<TipType, string> = {
|
|
info: 'bg-purple-500/10 border-purple-500/20 text-purple-300',
|
|
warning: 'bg-amber-500/10 border-amber-500/20 text-amber-300',
|
|
success: 'bg-green-500/10 border-green-500/20 text-green-300',
|
|
};
|
|
|
|
const prominentStyles: Record<TipType, string> = {
|
|
info: 'bg-gradient-to-br from-purple-500/5 via-cyan-500/5 to-purple-500/5 border-purple-500/30 text-gray-300 shadow-lg shadow-purple-500/10',
|
|
warning: 'bg-gradient-to-br from-amber-500/5 via-orange-500/5 to-amber-500/5 border-amber-500/30 text-gray-300 shadow-lg shadow-amber-500/10',
|
|
success: 'bg-gradient-to-br from-green-500/5 via-emerald-500/5 to-green-500/5 border-green-500/30 text-gray-300 shadow-lg shadow-green-500/10',
|
|
};
|
|
|
|
export const TipBox = ({ children, variant = 'compact', type = 'info' }: TipBoxProps) => {
|
|
const isCompact = variant === 'compact';
|
|
const icon = icons[type];
|
|
const styleClass = isCompact ? compactStyles[type] : prominentStyles[type];
|
|
|
|
if (isCompact) {
|
|
return (
|
|
<div
|
|
className={`flex gap-3 p-4 rounded-xl border ${styleClass}`}
|
|
role="note"
|
|
aria-label={`${type} note`}
|
|
>
|
|
<span className="text-lg flex-shrink-0">{icon}</span>
|
|
<div className="text-sm leading-relaxed">{children}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Prominent style
|
|
return (
|
|
<div
|
|
className={`p-6 rounded-2xl border ${styleClass}`}
|
|
role="alert"
|
|
aria-label={`${type} alert`}
|
|
>
|
|
<div className="text-base leading-relaxed">{children}</div>
|
|
</div>
|
|
);
|
|
};
|