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>
This commit is contained in:
@@ -4,8 +4,9 @@ import * as React from 'react';
|
||||
import Fuse from 'fuse.js';
|
||||
import { Input } from '@/components/ui/Input';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
import { Search, X, Heart, Clock, List } from 'lucide-react';
|
||||
import { Search, X, Heart, Clock, List, Shuffle } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils/cn';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import type { FigletFont } from '@/types/figlet';
|
||||
import { getFavorites, getRecentFonts, toggleFavorite, isFavorite } from '@/lib/storage/favorites';
|
||||
|
||||
@@ -13,12 +14,13 @@ export interface FontSelectorProps {
|
||||
fonts: FigletFont[];
|
||||
selectedFont: string;
|
||||
onSelectFont: (fontName: string) => void;
|
||||
onRandomFont?: () => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
type FilterType = 'all' | 'favorites' | 'recent';
|
||||
|
||||
export function FontSelector({ fonts, selectedFont, onSelectFont, className }: FontSelectorProps) {
|
||||
export function FontSelector({ fonts, selectedFont, onSelectFont, onRandomFont, className }: FontSelectorProps) {
|
||||
const [searchQuery, setSearchQuery] = React.useState('');
|
||||
const [filter, setFilter] = React.useState<FilterType>('all');
|
||||
const [favorites, setFavorites] = React.useState<string[]>([]);
|
||||
@@ -99,7 +101,20 @@ export function FontSelector({ fonts, selectedFont, onSelectFont, className }: F
|
||||
return (
|
||||
<Card className={className}>
|
||||
<div className="p-6">
|
||||
<h3 className="text-sm font-medium mb-4">Select Font</h3>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-sm font-medium">Select Font</h3>
|
||||
{onRandomFont && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onRandomFont}
|
||||
title="Random font"
|
||||
>
|
||||
<Shuffle className="h-4 w-4" />
|
||||
Random
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Filter Tabs */}
|
||||
<div className="flex gap-1 mb-4 p-1 bg-muted rounded-lg">
|
||||
|
||||
Reference in New Issue
Block a user