Files
kit-ui/components/ascii/FontSelector.tsx

211 lines
8.3 KiB
TypeScript
Raw Normal View History

'use client';
import * as React from 'react';
import Fuse from 'fuse.js';
import { Search, X, Heart, Clock, List, Shuffle } from 'lucide-react';
import { cn } from '@/lib/utils/cn';
import type { ASCIIFont } from '@/types/ascii';
import { getFavorites, getRecentFonts, toggleFavorite, isFavorite } from '@/lib/storage/favorites';
export interface FontSelectorProps {
fonts: ASCIIFont[];
selectedFont: string;
onSelectFont: (fontName: string) => void;
onRandomFont?: () => void;
className?: string;
}
type FilterType = 'all' | 'favorites' | 'recent';
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
const FILTERS: { value: FilterType; icon: React.ElementType; label: string }[] = [
{ value: 'all', icon: List, label: 'All' },
{ value: 'favorites', icon: Heart, label: 'Fav' },
{ value: 'recent', icon: Clock, label: 'Recent' },
];
export function FontSelector({
fonts,
selectedFont,
onSelectFont,
onRandomFont,
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
className,
}: FontSelectorProps) {
const [searchQuery, setSearchQuery] = React.useState('');
const [filter, setFilter] = React.useState<FilterType>('all');
const [favorites, setFavorites] = React.useState<string[]>([]);
const [recentFonts, setRecentFonts] = React.useState<string[]>([]);
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
const selectedRef = React.useRef<HTMLButtonElement>(null);
React.useEffect(() => {
setFavorites(getFavorites());
setRecentFonts(getRecentFonts());
}, []);
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
// Keep selected item in view when font changes externally (e.g. random)
React.useEffect(() => {
selectedRef.current?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}, [selectedFont]);
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
const fuse = React.useMemo(
() => new Fuse(fonts, { keys: ['name', 'fileName'], threshold: 0.3, includeScore: true }),
[fonts]
);
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
const filteredFonts = React.useMemo(() => {
let base = fonts;
if (filter === 'favorites') {
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
base = fonts.filter((f) => favorites.includes(f.name));
} else if (filter === 'recent') {
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
base = [...fonts.filter((f) => recentFonts.includes(f.name))].sort(
(a, b) => recentFonts.indexOf(a.name) - recentFonts.indexOf(b.name)
);
}
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
if (!searchQuery) return base;
const hits = fuse.search(searchQuery).map((r) => r.item);
return filter === 'all' ? hits : hits.filter((f) => base.includes(f));
}, [fonts, searchQuery, fuse, filter, favorites, recentFonts]);
const handleToggleFavorite = (fontName: string, e: React.MouseEvent) => {
e.stopPropagation();
toggleFavorite(fontName);
setFavorites(getFavorites());
};
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
const emptyMessage =
filter === 'favorites'
? 'No favorites yet — click ♥ to save'
: filter === 'recent'
? 'No recent fonts'
: searchQuery
? 'No fonts match your search'
: 'Loading fonts…';
return (
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
<div className={cn('glass rounded-xl p-3 flex flex-col min-h-0 overflow-hidden', className)}>
{/* ── Header ────────────────────────────────────────────── */}
<div className="flex items-center justify-between mb-3 shrink-0">
<span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
Fonts
</span>
<div className="flex items-center gap-2.5">
<span className="text-[10px] text-muted-foreground/35 font-mono tabular-nums">
{fonts.length}
</span>
{onRandomFont && (
<button
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
onClick={onRandomFont}
className="text-muted-foreground/50 hover:text-primary transition-colors"
title="Random font"
>
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
<Shuffle className="w-3.5 h-3.5" />
</button>
)}
</div>
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
</div>
{/* ── Filter tabs ───────────────────────────────────────── */}
<div className="flex glass rounded-lg p-0.5 gap-0.5 mb-3 shrink-0">
{FILTERS.map(({ value, icon: Icon, label }) => (
<button
key={value}
onClick={() => setFilter(value)}
className={cn(
'flex-1 flex items-center justify-center gap-1.5 py-1.5 rounded-md text-xs font-medium transition-all',
filter === value
? 'bg-primary text-primary-foreground shadow-sm'
: 'text-muted-foreground hover:text-foreground'
)}
>
<Icon className="w-3 h-3" />
{label}
</button>
))}
</div>
{/* ── Search ────────────────────────────────────────────── */}
<div className="relative mb-3 shrink-0">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3 h-3 text-muted-foreground/40 pointer-events-none" />
<input
type="text"
placeholder="Search fonts…"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full bg-transparent border border-border/40 rounded-lg pl-8 pr-7 py-1.5 text-xs font-mono outline-none focus:border-primary/50 transition-colors placeholder:text-muted-foreground/30"
/>
{searchQuery && (
<button
onClick={() => setSearchQuery('')}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground/40 hover:text-muted-foreground transition-colors"
>
<X className="w-3 h-3" />
</button>
)}
</div>
{/* ── Font list ─────────────────────────────────────────── */}
<div className="flex-1 min-h-0 overflow-y-auto scrollbar-thin scrollbar-thumb-primary/20 scrollbar-track-transparent space-y-0.5 pr-0.5">
{filteredFonts.length === 0 ? (
<div className="py-10 text-center">
<p className="text-xs text-muted-foreground/35 italic">{emptyMessage}</p>
</div>
) : (
filteredFonts.map((font) => {
const isSelected = selectedFont === font.name;
const fav = isFavorite(font.name);
return (
<div
key={font.name}
className={cn(
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
'group flex items-center gap-1.5 rounded-lg transition-all cursor-pointer',
'border-l-2',
isSelected
? 'bg-primary/10 border-primary text-primary'
: 'border-transparent text-foreground/65 hover:bg-primary/8 hover:text-foreground'
)}
>
<button
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
ref={isSelected ? selectedRef : undefined}
onClick={() => onSelectFont(font.name)}
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
className="flex-1 text-left text-xs font-mono truncate px-2 py-1.5"
>
{font.name}
</button>
<button
onClick={(e) => handleToggleFavorite(font.name, e)}
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
className={cn(
'shrink-0 pr-2 transition-all',
fav ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'
)}
aria-label={fav ? 'Remove from favorites' : 'Add to favorites'}
>
<Heart
className={cn(
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
'w-3 h-3 transition-colors',
fav ? 'fill-rose-500 text-rose-500' : 'text-muted-foreground/40 hover:text-rose-400'
)}
/>
</button>
</div>
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
);
})
)}
</div>
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
{/* ── Footer ────────────────────────────────────────────── */}
<div className="mt-3 pt-2.5 border-t border-border/25 flex items-center justify-between shrink-0">
<span className="text-[10px] text-muted-foreground/35 font-mono tabular-nums">
{filteredFonts.length} font{filteredFonts.length !== 1 ? 's' : ''}
refactor(ascii): align layout and UX with Calculate blueprint Rewrites all four ASCII tool components to share the same design language and spatial structure as the Calculator & Grapher tool. Layout - New responsive 2/5–3/5 grid (was fixed 2+1 col); matches Calculate - Left panel: text input card + font selector filling remaining height - Right panel: preview as the dominant full-height element - Mobile: tabbed Editor / Preview switcher (same pattern as Calculator) TextInput - Replace shadcn Textarea with native <textarea> - Glass border pattern (border-border/40, focus:border-primary/50) - Monospace font, consistent counter styling FontSelector - Replace Card + shadcn Tabs + Button + Input + Empty with native elements - Glass panel (glass rounded-xl) matching Calculate panel style - Custom tab strip mirrors Calculator mobile tab pattern - Native search input with glass border - Font list items: border-l-2 left accent for selected state, hover:bg-primary/8, rose heart for favorites - Auto-scrolls selected item into view on external changes - Simplified empty state to single italic line FontPreview - Replace Card + Button + Badge + ToggleGroup + Tooltip + Empty - Glass panel with header row (label + font tag + action buttons) - Controls row: native toggle buttons with primary/10 active state - Terminal window: dark #06060e background, macOS-style chrome (rose/amber/emerald dots), font name watermark — the hero element - PNG export captures entire terminal including chrome at 2x - Inline skeleton loader with pulse animation replaces Skeleton import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 07:46:21 +01:00
</span>
{filter === 'favorites' && (
<span className="text-[10px] text-muted-foreground/35">{favorites.length} saved</span>
)}
{filter === 'recent' && (
<span className="text-[10px] text-muted-foreground/35">{recentFonts.length} recent</span>
)}
</div>
</div>
);
}