Files
figlet-ui/components/converter/FontPreview.tsx
Sebastian Krüger 704695f14f feat: add toast notifications, random font, and font info display
Major UX enhancements for better user feedback and discovery:

**Toast Notification System**
- Beautiful toast notifications with 3 types (success/error/info)
- Auto-dismiss after 3 seconds
- Slide-in animation from right
- Color-coded by type (green/red/blue)
- Dark mode support
- Close button for manual dismiss
- ToastProvider context for global access
- Non-blocking UI overlay

**Random Font Discovery**
- Shuffle button in font selector
- One-click random font selection
- Toast notification shows selected font
- Perfect for discovering new fonts
- Located next to "Select Font" header

**Enhanced Font Preview**
- Font name badge display
- Character count statistics
- Line count statistics
- Better visual hierarchy
- Responsive stat display

**Improved Feedback**
- Toast on copy: "Copied to clipboard!"
- Toast on share: "Shareable URL copied!"
- Toast on random: "Random font: FontName"
- Error toasts for failed operations
- Removed temporary text replacement

**Smooth Animations**
- Slide-in animation for toasts
- Fade-in animation class
- Custom keyframe animations
- CSS utility classes
- Smooth transitions throughout

**Technical Improvements**
- useToast custom hook
- Context-based state management
- Auto-cleanup with setTimeout
- Unique toast IDs
- TypeScript types for toast system
- Proper event propagation

**Better UX**
- No more jarring text replacements
- Non-intrusive notifications
- Professional feedback system
- Discoverable random feature
- Informative preview stats

The app now feels polished and professional with proper user feedback!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 13:21:13 +01:00

83 lines
2.8 KiB
TypeScript

'use client';
import * as React from 'react';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Copy, Download, Share2 } from 'lucide-react';
import { cn } from '@/lib/utils/cn';
export interface FontPreviewProps {
text: string;
font?: string;
isLoading?: boolean;
onCopy?: () => void;
onDownload?: () => void;
onShare?: () => void;
className?: string;
}
export function FontPreview({ text, font, isLoading, onCopy, onDownload, onShare, className }: FontPreviewProps) {
const lineCount = text ? text.split('\n').length : 0;
const charCount = text ? text.length : 0;
return (
<Card className={cn('relative', className)}>
<div className="p-6">
<div className="flex items-center justify-between mb-4 flex-wrap gap-2">
<div className="flex items-center gap-2">
<h3 className="text-sm font-medium">Preview</h3>
{font && (
<span className="text-xs px-2 py-0.5 bg-primary/10 text-primary rounded-md font-mono">
{font}
</span>
)}
</div>
<div className="flex gap-2 flex-wrap">
{onCopy && (
<Button variant="outline" size="sm" onClick={onCopy}>
<Copy className="h-4 w-4" />
Copy
</Button>
)}
{onShare && (
<Button variant="outline" size="sm" onClick={onShare} title="Copy shareable URL">
<Share2 className="h-4 w-4" />
Share
</Button>
)}
{onDownload && (
<Button variant="outline" size="sm" onClick={onDownload}>
<Download className="h-4 w-4" />
Download
</Button>
)}
</div>
</div>
{!isLoading && text && (
<div className="flex gap-4 mb-2 text-xs text-muted-foreground">
<span>{lineCount} lines</span>
<span></span>
<span>{charCount} chars</span>
</div>
)}
<div className="relative min-h-[200px] bg-muted/50 rounded-lg p-4 overflow-x-auto">
{isLoading ? (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-sm text-muted-foreground">Generating...</div>
</div>
) : text ? (
<pre className="font-mono text-xs sm:text-sm whitespace-pre overflow-x-auto">
{text}
</pre>
) : (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-sm text-muted-foreground">Your ASCII art will appear here</div>
</div>
)}
</div>
</div>
</Card>
);
}